1

Could somebody explain why b = 150 ?

#define CUBE(X) ((X) * (X) * (X))

using namespace std;

int main( void )
{
    int a = 3,b = 0;  

    cout << "before "<< endl;
    cout << "a = " << a;
    cout << endl;
    cout << "b = " << b;
    cout << endl;
    cout << "after"<< endl;
    b = CUBE( ++a );
    cout << "a = " << a;
    cout << endl;
    cout << "b = " << b;
    getchar();
    return 0;
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
wolf3d
  • 112
  • 2
  • 11

3 Answers3

10

Because you're using a macro. Macros are not functions.

The line:

b = CUBE( ++a );

gets re-written as:

b = ((++a) * (++a) * (++a))

before your code compiles.

The code then invokes Undefined Behaviour because you increment a several times between sequence points.

It would be better if you used a function instead.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • yes i know that inline functions are better, but i just need the answer to this question ;) i understand situation if i got b = CUBE( a++ ); – wolf3d May 30 '11 at 19:40
  • 2
    @wolf3d: The situation is the same with `++a` as it is with `a++`. Any collection of operations that alter and read `a` between sequence points is undefined. – Lightness Races in Orbit May 30 '11 at 19:42
  • 1
    @wol3d: As Tomalak Geret'kal said with `a++` the behaviour is not defined. Maybe you understood what code the compiler has generated, but this does not mean that every compiler will do it the same, or that other versions of the same compiler will do the same. – Benoit May 30 '11 at 19:49
  • Thank You for replay, read it all and I figured out the b's value on peace of paper :D – wolf3d May 30 '11 at 20:09
  • @wolf3d: How could you figure it out on a piece of paper? There's no wrong answer here. My compiler gives 216. – Benjamin Lindley May 30 '11 at 20:26
  • @wolf3d: Benjamin said "there's no wrong answer here" with respect to the various evaluations of the final result of `b`, whereas in fact every answer is wrong because the final result of `b` is undefined. – Lightness Races in Orbit May 30 '11 at 20:57
  • i misunderstood this statement... my english and c++ understanding isnt the best... sry – wolf3d May 30 '11 at 21:01
  • @wolf3d: No problem; I realised it was slightly unclear as I rewrote it. – Lightness Races in Orbit May 30 '11 at 21:04
  • @Tomalak: When I say "there's no wrong answer here", that means that any answer the compiler gives is perfectly acceptable. – Benjamin Lindley May 30 '11 at 21:04
  • @Benjamin: No it's not, because it's UB. Not sure how else to say it! – Lightness Races in Orbit May 30 '11 at 21:05
  • @Tomalak: So, you're saying that if the compiler gives an answer of 150 or 216, it's not acceptable? – Benjamin Lindley May 30 '11 at 21:06
  • @Benjamin: That's right. It's not acceptable. The code is broken, because it invokes UB. You should throw away the result, fix the code, and start again. – Lightness Races in Orbit May 30 '11 at 21:09
  • @Tomalak: Yes, obviously the code is not acceptable. I'm not saying that the code is okay. Obviously I'm talking about the compiler's behavior in response to the code. – Benjamin Lindley May 30 '11 at 21:11
  • @Benjamin: The compiler's behaviour _can be anything_. It is undefined. You may get a value of 150, or of 216, or of 999.. or your computer may explode, or a black hole may form in your armpit. Is that "acceptable"? – Lightness Races in Orbit May 30 '11 at 21:12
  • @Tomalak: "The compiler's behaviour can be anything". That's exactly what I mean by "there is no wrong answer". – Benjamin Lindley May 30 '11 at 21:14
3

(++a) * (++a) * (++a) is undefined behaviour.

Community
  • 1
  • 1
Benoit
  • 76,634
  • 23
  • 210
  • 236
3

Undefined behaviour- you modify a more than once between sequence points. This is why inline functions are the vastly superior option.

Puppy
  • 144,682
  • 38
  • 256
  • 465