Reputation: 5050
Which macro statement may cause an unexpected results ?
#define YEAR_LENGTH 365
#define MONTH_LENGTH 30
#define DAYCALC(y, m, d) ((y * YEAR_LENGTH) + (m * MONTH_LENGTH) + d)
int main()
{
int x = 5, y = 4 , z = 1;
cout << DAYCALC(x *3 , y %3 , z) << endl ;
cout << DAYCALC(x +12 , y , 300) << endl ;
cout << DAYCALC(x , 40 - y , 3+z) << endl ;
cout << DAYCALC(x , y , (z+50)) << endl ;
cout << DAYCALC(x , y %3 , z) << endl ;
cout << DAYCALC(4 % x , y++ , z) << endl;
return 0;
}
I run the program very well w/o any unexpected results.
Are there some hidden exceptions ?
Upvotes: 2
Views: 427
Reputation: 6297
You need to change DAYCALC;
#define DAYCALC(y, m, d) ( ((y) * YEAR_LENGTH) + ((m) * MONTH_LENGTH) + (d) )
That way, if m is say 3+z, then the inner term will be the correct;
(3+z) * MONTH_LENGTH
not the incorrect;
3 + z*MONTH_LENGTH
Upvotes: 2
Reputation: 4835
you can check what will happen after macro expansion by g++ -E .
int main()
{
int x = 5, y = 4 , z = 1;
cout << ((x *3 * 365) + (y %3 * 30) + z) << endl ;
cout << ((x +12 * 365) + (y * 30) + 300) << endl ;
cout << ((x * 365) + (40 - y * 30) + 3+z) << endl ; //precedence problem
cout << ((x * 365) + (y * 30) + (z+50)) << endl ;
cout << ((x * 365) + (y %3 * 30) + z) << endl ;
cout << ((4 % x * 365) + (y++ * 30) + z) << endl;
return 0;
}
Upvotes: 7
Reputation: 471569
You have an operator precendence problem. Macros are literally expanded as text copy and paste.
For example:
DAYCALC(x , 40 - y , 3+z)
gets expanded to:
((40 - y * YEAR_LENGTH) + (x * MONTH_LENGTH) + 3+z)
Note that 40 - y * YEAR_LENGTH
, is not what you want due to operator precedence.
So you need to put ()
around your parameters in the macro:
#define DAYCALC(y, m, d) (((y) * YEAR_LENGTH) + ((m) * MONTH_LENGTH) + (d))
In general, if a macro parameter appears more than once in the macro, side effects such as y++
(in your last statement) will also be applied more than once. So it's something to be careful of.
Upvotes: 8