Skip Navigation LinksHome > Categories > Code from a Category

6 Essential C Plus Plus Interview Questions



User Name: toptal
Name: toptal.com
Contact Me: https://www.toptal.com/contact
Home Page: www.toptal.com
Toptal is an exclusive network of the top freelance software developers and designers in the world. Top companies rely on Toptal freelancers for their most important projects. [More]
Viewed Times: 613
Add Date: 01/22/2016
Comprehensive, community-driven list of essential C++ interview questions.
1. What will the line of code below print out and why?
cout << 25u - 50;

The answer is not -25. Rather, the answer (which will surprise many) is 4294967271, assuming 32 bit integers. Why?

In C++, if the types of two operands differ from one another, then the operand with the “lower type” will be promoted to the type of the “higher type” operand, using the following type hierarchy (listed here from highest type to lowest type): long double, double, float, unsigned long int, long int, unsigned int, int (lowest).

So when the two operands are, as in our example, 25u (unsigned int) and 50 (int), the 50 is promoted to also being an unsigned integer (i.e., 50u).

Moreover, the result of the operation will be of the type of the operands. Therefore, the result of 25u - 50u will itself be an unsigned integer as well. So the result of -25 converts to 4294967271 when promoted to being an unsigned integer.

2. C++ supports multiple inheritance. What is the “diamond problem” that can occur with multiple inheritance? Give an example.

Let’s consider a simple example. A university has people who are affiliated with it. Some are students, some are faculty members, some are administrators, and so on. So a simple inheritance scheme might have different types of people in different roles, all of whom inherit from one common “Person” class. The Person class could define an abstract getRole() method which would then be overridden by its subclasses to return the correct role type.

But now what happens if we want to model a the role of a Teaching Assistant (TA)? Typically, a TA is both a grad student and a faculty member. This yields the classic diamond problem of multiple inheritance and the resulting ambiguity regarding the TA’s getRole() method.

Which getRole() implementation should the TA inherit? That of the Faculty Member or that of the Grad Student? The simple answer might be to have the TA class override the getRole() method and return newly-defined role called “TA”. But that answer is also imperfect as it would hide the fact that a TA is, in fact, both a faculty member and a grad student.

3. What is the error in the code below and how should it be corrected?

my_struct_t *bar;
/* ... do stuff, including setting bar to point to a defined my_struct_t object ... */
memset(bar, 0, sizeof(bar));


The last argument to memset should be sizeof(*bar), not sizeof(bar). sizeof(bar) calculates the size of bar (i.e., the pointer itself) rather than the size of the structure pointed to by bar.

The code can therefore be corrected by using sizeof(*bar) as the last argument in the call to memset.

A sharp candidate might point out that using *bar will cause a dereferencing error if bar has not been assigned. Therefore an even safer solution would be to use sizeof(my_struct_t). However, an even sharper candidate must know that in this case using *bar is absolutely safe within the call to sizeof, even if bar has not been initialized yet, since sizeof is a compile time construct.

4. What will i and j equal after the code below is executed? Explain your answer.
int i = 5;
int j = i++;


After the above code executes, i will equal 6, but j will equal 5.

Understanding the reason for this is fundamental to understanding how the unary increment (++) and decrement (--) operators work in C++.

When these operators precede a variable, the value of the variable is modified first and then the modified value is used. For example, if we modified the above code snippet to instead say int j = ++i;, i would be incremented to 6 and then j would be set to that modified value, so both would end up being equal to 6.

However, when these operators follow a variable, the unmodified value of the variable is used and then it is incremented or decremented. That’s why, in the statement int j = i++; in the above code snippet, j is first set to the unmodified value of i (i.e., 5) and then i is incremented to 6.

5. What is the problem in the code below? What would be an alternate way of implementing this that would avoid the problem?

size_t sz = buf->size();
while ( --sz >= 0 )
{
/* do something */
}

The problem in the above code is that --sz >= 0 will always be true so you’ll never exit the while loop (so you’ll probably end up corrupting memory or causing some sort of memory violation or having some other program failure, depending on what you’re doing inside the loop).

The reasons that --sz >= 0 will always be true is that the type of sz is size_t. size_t is really just an alias to one of the fundamental unsigned integer types. Therefore, since sz is unsigned, it can never be less than zero (so the condition can never be true).

One example of an alternative implementation that would avoid this problem would be to instead use a for loop as follows:
for (size_t i = 0; i < sz; i++)
{
/* do something */
}


6.Consider the two code snippets below for printing a vector. Is there any advantage of one vs. the other? Explain.

Option 1:

vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); itr++) {
itr->print();

}
Option 2:
vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); ++itr) {
itr->print();
}


Although both options will accomplish precisely the same thing, the second option is better from a performance standpoint. This is because the post-increment operator (i.e., itr++) is more expensive than pre-increment operator (i.e., ++itr). The underlying implementation of the post-increment operator makes a copy of the element before incrementing it and then returns the copy.

This article was originally published on Toptal

Post a Comment

Name: (Optional)
Email: (Optional, you can get an email if somebody replys your comments)*
Email me if somebody respons my comment below:
Details**:
Enter Text
as Below:
(case insensitive, if hard to read, click the "get a new one" button)
 
    
* Your email address will not be shared with any third parties for any reason.
** Maximum 1000 charactors.