Need help with Macros

Output of the following program for "J" should be ++y * ++y = 2 * 3 = 6. But when I execute this program, I get Output as 9. I tried on several compilers (GNU GCC).
Can someone please help me out with this

1
2
3
4
5
6
7
8
9
10
#include<iostream>
using namespace std;
#define DOUBLE(X) X*X

int main(){
    int y=1;
    int j = DOUBLE(++y);
    cout<<"J is -> "<<j;
    return 0;
}
You don't want to do something like that, doing ++y * ++y is undefined behavior because you don't know in what order the program will modify the values.

In general, in order to be clear, you should increment y on its own line.
The compiler may issue a warning, such as:
[Warning] operation on 'y' may be undefined [-Wsequence-point]

The behaviour is undefined. See for example:
http://www.cplusplus.com/forum/beginner/104484/
> ++y * ++y
that's undefined behaviour
http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points

You cannot fix the macro, but given that you are using c++ you may utilize a template instead
1
2
3
4
template <class T>
T square(T x){
   return x*x;
}



Your macro would also fail in the case DOUBLE( y+1 ) because of precedence
(remember that is simply text substitution)
++ takes precedence over * so both sides get ++'ed before the *

I disagree this is a sequence point issue, it looks like simple operator precedence to me.


EDIT:

After reading ne555's link, I've changed my mind on the sequence point issue. Because it modifies y twice it is definitely a sequence point issue.

However, i stand by my answer to the question as to whats happening.

Take this example:
int y=1; int i = ++y + ++y * ++y;

gcc 4.3 and vs2010 equated to int i = 4 + 2 * 3; = 10

and JS and PHP equated to int i = 2 + 3 * 4; = 14

I think this is because interpreted languages manifest their side effects at parse time, while compiled languages manifest their side effects at run time.
Last edited on
It really isn't related to interpreted versus compiled languages. Undefined behaviour is undefined behaviour, it's no use trying to deduce rules, since each compiler may give a different result.

(See for example the post I linked previously where different compilers give a variety of differing outputs).
Thanks a lot to all of you for such a quick responses. I will try to avoid this undefined behavior.

@jaybob66 - I agree to your point about operator precedence, which is true in the example which I posted. But after reading all the other replies, I think problem is not with macros, its with pre and post fix operation execution by compilers. See below example O/P for cout operator

1
2
3
4
5
6
7
8
9
10
<< i   << i++               => 2 1
<< i++ << i                 => 1 2
<< i++ << i++               => 2 1
<< i++ << i   << i          => 1 2 2
<< i++ << i++ << i          => 2 1 3
<< i++ << i++ << i++        => 3 2 1
<< i++ << i   << i   << i   => 1 2 2 2
<< i++ << i++ << i   << i   => 2 1 3 3
<< i++ << i++ << i++ << i   => 3 2 1 4
<< i++ << i++ << i++ << i++ => 4 3 2 1



after analyzing 1st line, I thought cout operator executes from right to left. Means first i++ is processed, then i which results in 2 1 as o/p.
But second o/p doesn't agree with the above logic.
Last edited on
> See below example O/P for cout operator
All those are undefined behaviour.

> I thought cout operator executes from right to left
the function arguments may be evaluated in any order

> I think problem is not with macros
macros are evil
http://www.parashift.com/c++-faq/inline-vs-macros.html
Last edited on
Topic archived. No new replies allowed.