When writing code, the macro (#define) command is often used. Recently, I encountered two instances where macros were misused, so I’ll analyze them here.
Forgetting that macro parameters are simply replaced
The code is as follows:
1 |
|
The above code implements a simple program to determine the larger of two numbers, and there is no issue here. However, problems arise when the parameters of MAX have side effects:
1 | cout<<MAX(a--,b)<<endl; |
When the parameter of MAX is MAX(a–,b), if the input data is a>b, then an error occurs:
After running, although the MAX value is 11, after executing cout<<MAX(a--,b)<<endl;
, the value of a changes to 10.
Since define is just simple macro replacement
, when the parameter of MAX has side effects, it becomes:
1 |
|
This means that if the input data is a>b, then a--
will be executed twice.
After rewriting the MAX macro into an equivalent if statement, the running result is as follows:
It matches the result of executing the MAX macro.
Ambiguity caused by a lack of parentheses in the macro
In the previous code, #define MAX(a,b) a>=b?a:b
is wrong for the following reasons. In this case, if there are other expressions in the calling statement, it can also cause ambiguity! Consider the following code:
1 |
|
Here, int max=MAX(a,b)*2;
we expect to multiply the larger value between a and b by 2 and assign it to the variable max
. However, as mentioned earlier, macros are just simple replacements, so the actual meaning of the above code is:
1 |
|
The running result is as follows:
When a>=b, 2 will not be executed because the compiler treats b2 as an expression of the ternary operator.
Therefore, the safest and most correct way to write macro commands is:
- The macro command must include parentheses to ensure that the macro command acts as an independent expression.
- The macro parameters must also include parentheses to ensure the correct usage of each parameter (ensuring that side effects do not affect other parameters).
1 |
Note: Always remember that a macro is just a simple and crude replacement, which may cause ambiguity!