1

I had a job interview where I was asked two questions I couldn't solve. I would like to know what the problems with the following two snippets of code are

First question:

The question was: what's wrong in the following code?

class A
{
    // Some properties ans methods
};

class B
{
    // Some properties ans methods
};

void foo(A* pa, B* pb)
{
    //Do somthing with pa and pb
};

void main()
{
    A* pa = NULL;
    B* pb = NULL;
    foo(pa = new A, pb = new B);
}

Second question:

The question was: what is printed (Eventually, the interviewer told me that the answer is 17 and 0, but I don't understand why)

int counter = 0; //Global variable

int foo()
{
    int i = 0;
    while (i < 12)
    {
        // Do somthing
        counter++;
        i++;
    }
    return 17;
}

void main()
{
    printf("Foo() = %d , counter = %d", foo(), counter);
}
Tas
  • 7,023
  • 3
  • 36
  • 51
HolyM
  • 301
  • 3
  • 9
  • 1
    What are your current solutions? What have you done? What do you think? – M. Shaw Jul 31 '15 at 06:24
  • 12
    With questions like that, don't take the job, even if you pass the interview. – juanchopanza Jul 31 '15 at 06:24
  • 6
    @SpiderMan It *could* be `0`. But it doesn't have to be. – juanchopanza Jul 31 '15 at 06:25
  • 1
    It could be zero. If the example is something like int r = foo(); int v = counter; printf("Foo() = %d , counter = %d", r, r); then second value is always 12, But, printf could retrieve counter value before executing foo func. I have tried example on repl.it and always got 0 for second printed value. Maybe this depends on compiler, or printf implementation or some optimization checks. Nevertheless, I think this is stupid question – Igor Jul 31 '15 at 06:32
  • 1
    @SpiderMan clarification on juanchopanza's point. There are no guarantees on which which parameter is going to be processed first. Counter could go on the stack as zero before foo is called or as 12 after foo is called. You have no way of knowing which way the compiler will choose to go. – user4581301 Jul 31 '15 at 06:34

5 Answers5

13

There are two things wrong in the programs, both the same problem, and I will deal with the biggest one first.

void main() is not valid C++! main() must return an int! Bjarne Stroustrup said so himself!

The second problem is that C++ leaves the order of evaluation of function arguments unspecified, which means that both programs can have potential problems.

foo(pa = new A, pb = new B);

The A or B may get allocated first (it doesn't matter which) and if the other throws an exception during allocation, then you will leak memory. Both objects should be created first then passed into foo. Of course, you'd use smart pointers though ;)

printf("Foo() = %d , counter = %d", foo(), counter);

counter may either be 0 or 12. It depends on whether counter is evaluated before foo or the other way around, which C++ leaves unspecified. Again, you should run foo first, store the value, then use printf. But of course, you'd use a std::stringstream for this anyway!

alseether
  • 1,889
  • 2
  • 24
  • 39
Tas
  • 7,023
  • 3
  • 36
  • 51
  • I don't think there is anything that says `counter` will be evaluated *before* or *after* `foo()`. In that case, the second code snippet has undefined behaviour. – juanchopanza Jul 31 '15 at 06:46
  • Thank you, your answer about first question sounds good i didn't thought about it. regard to second question counter isn't evaluated before foo. – HolyM Jul 31 '15 at 07:18
7

You can nitpick about both programs, but both are invalid, as there is no valid entry point defined.

void main()

This is not a valid C++ entry point to a program. Therefor the whole thing is undefined behavior.

That's probably not what the interviewer wanted to know, but don't take trivia questions from a guy who gets the basics wrong.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • Nice didn't think about that! – Torsten Hopf Jul 31 '15 at 06:34
  • 2
    Thank you, i said about void main() but he says that not the main problem. – HolyM Jul 31 '15 at 07:13
  • 2
    Well, it *is* the main problem. Sure, it does not compile because it's missing a header. It's has memory leak. But the **real** problem is that your interviewer had no clue about C++. Both are undefined behavior and it does not get any worse than your program start being undefined behavior. – nvoigt Jul 31 '15 at 09:06
1

For the second question it is unspecified whether the printf() will print 0 or 12 for counter. The order of evaluation for foo() and counter is unspecified.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 1
    @juanchopanza: I agree. I personally don't want to worry about the distinction here - regardless it's a bug since you can't count on what's going to happen. Either (an answer of unspecified or undefined behavior) is a better answer than was given to the OP. – Michael Burr Jul 31 '15 at 06:39
-2

Hey the answer for your second first question is, CAN BE zero is printed because as @Andreas said the order in which the arguments are processed is not defined, so it can be 0, because you increase it in foo().

To your first first question:

First let me tell you that you should avoid using NULL if you want to set your pointer as nullpointer, if you're using C++11, because NULL is not recognized by the compiler as pointer type (see Scott Meyer's More Effective C++). You should use nullptr instead. I am not really sure if the compiler would accept that foo(pa = new A, pb = new B); statement, it looks like the syntax for a funtion with standard parameters maybe someone else can give a hint in the comments.

Torsten Hopf
  • 69
  • 10
-6

In second question , whatever the codes inside foo() , it will always return '17'

Now , as counter is global variable , its value is manipulated inside foo() , so when in main() , the printf() ; uses counter the value of counter will be initialized to zero as it is a global variable.

It is not static that its value will be changed permanently.

Bhavesh Kumar
  • 116
  • 1
  • 9