Using Parentheses in Define Preprocessor Statements - c

So I was wondering when is to use
#define xxx (yyy)
vs
#define xxx yyy
My project includes a files that has its own defines such at AD0_ADMD_CT if I wanted to redefine them would I need to use (AD0_ADMD_CT) or just AD0_ADMD_CT in the define or not?
AD0_ADMD_CT is a defined as
#define AD1_ADMD_CT (IO_AD1.ADMD.bit.CT)
So it would be either
#define AD0_COMPARETIME (AD0_ADMD_CT)
or
#define AD0_COMPARETIME AD0_ADMD_CT

There is no difference in both. In first case XXX is replaced by yyy and by (yyy) is second case. The convention to use brackts is to avoid logical errors that may occur. For example you define addition function as:
#define f(N) N+N
int a = f(5)*f(5)
Expected value is 10*10 = 100 , but output is 35 because at compile time is becomes
int a = 5+5*5+5, so using operator preference rule, output changes.
So parenthesis avoid these type of errors.

By adding parentheses, you are forcing the argument inside the parentheses to be evaluated before the rest of the macro body, so if you had
#define MULT(x, y) (x) * (y)
// now MULT(3 + 2, 4 + 2) will expand to (3 + 2) * (4 + 2)
It does not appear to affect your current case unless there is more to your macros.

It's very important if you have operators in your macro. For example:
#define ADD(x,y) x + y
ADD(1,2) * 3 /* Should be 9, is 7 */
Should be:
#define ADD(x,y) (x + y)
ADD(1,2) * 3 /* 7 */
These precedence problems also apply for the arguments, as #Gi Joe says, and need to be wrapped in parens for precedence.
However, for a macro like:
#define MAGICNUM 3
It doesn't matter.

An important thing to remember is that the preprocessor simply expands macros. For example, if you had the following lines:
#define AD0_COMPARETIME_1 (AD0_ADMD_CT)
#define AD0_COMPARETIME_2 AD0_ADMD_CT
num_1 = AD0_COMPARETIME_1;
num_2 = AD0_COMPARETIME_2;
After the first expansion you'd have this:
num_1 = (AD0_ADMD_CT);
num_2 = AD0_ADMD_CT;
And after the second expansion you'd have this:
num_1 = ((IO_AD1.ADMD.bit.CT));
num_2 = (IO_AD1.ADMD.bit.CT);
A problem may arise, as stated in other answers, when an expression is expanded.

Related

defining proper Macros in C [duplicate]

This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 5 years ago.
I tried to play with the definition of the macro SQR in the following code:
#define SQR(x) (x*x)
int main()
{
int a, b=3;
a = SQR(b+5); // Ideally should be replaced with (3+5*5+3), though not sure.
printf("%d\n",a);
return 0;
}
It prints 23. If I change the macro definition to SQR(x) ((x)*(x)) then the output is as expected, 64. I know that a call to a macro in C replaces the call with the definition of the macro, but I still can’t understand, how it calculated 23.
Pre-processor macros perform text-replacement before the code is compiled so
SQR(b+5) translates to
(b+5*b+5) = (6b+5) = 6*3+5 = 23
Regular function calls would calculate the value of the parameter (b+3) before passing it to the function, but since a macro is pre-compiled replacement, the algebraic order of operations becomes very important.
Consider the macro replacement using this macro:
#define SQR(x) (x*x)
Using b+5 as the argument. Do the replacement yourself. In your code, SQR(b+5) will become: (b+5*b+5), or (3+5*3+5). Now remember your operator precedence rules: * before +. So this is evaluated as: (3+15+5), or 23.
The second version of the macro:
#define SQR(x) ((x) * (x))
Is correct, because you're using the parens to sheild your macro arguments from the effects of operator precedence.
This page explaining operator preference for C has a nice chart. Here's the relevant section of the C11 reference document.
The thing to remember here is that you should get in the habit of always shielding any arguments in your macros, using parens.
Because (3+5*3+5 == 23).
Whereas ((3+5)*(3+5)) == 64.
The best way to do this is not to use a macro:
inline int SQR(int x) { return x*x; }
Or simply write x*x.
The macro expands to
a = b+5*b+5;
i.e.
a = b + (5*b) + 5;
So 23.
After preprocessing, SQR(b+5) will be expanded to (b+5*b+5). This is obviously not correct.
There are two common errors in the definition of SQR:
do not enclose arguments of macro in parentheses in the macro body, so if those arguments are expressions, operators with different precedences in those expressions may cause problem. Here is a version that fixed this problem
#define SQR(x) ((x)*(x))
evaluate arguments of macro more than once, so if those arguments are expressions that have side effect, those side effect could be taken more than once. For example, consider the result of SQR(++x).
By using GCC typeof extension, this problem can be fixed like this
#define SQR(x) ({ typeof (x) _x = (x); _x * _x; })
Both of these problems could be fixed by replacing that macro with an inline function
inline int SQR(x) { return x * x; }
This requires GCC inline extension or C99, See 6.40 An Inline Function is As Fast As a Macro.
A macro is just a straight text substitution. After preprocessing, your code looks like:
int main()
{
int a, b=3;
a = b+5*b+5;
printf("%d\n",a);
return 0;
}
Multiplication has a higher operator precedence than addition, so it's done before the two additions when calculating the value for a. Adding parentheses to your macro definition fixes the problem by making it:
int main()
{
int a, b=3;
a = (b+5)*(b+5);
printf("%d\n",a);
return 0;
}
The parenthesized operations are evaluated before the multiplication, so the additions happen first now, and you get the a = 64 result that you expect.
Because Macros are just string replacement and it is happens before the completion process. The compiler will not have the chance to see the Macro variable and its value. For example: If a macro is defined as
#define BAD_SQUARE(x) x * x
and called like this
BAD_SQUARE(2+1)
the compiler will see this
2 + 1 * 2 + 1
which will result in, maybe, unexpected result of
5
To correct this behavior, you should always surround the macro-variables with parenthesis, such as
#define GOOD_SQUARE(x) (x) * (x)
when this macro is called, for example ,like this
GOOD_SQUARE(2+1)
the compiler will see this
(2 + 1) * (2 + 1)
which will result in
9
Additionally, Here is a full example to further illustrate the point
#include <stdio.h>
#define BAD_SQUARE(x) x * x
// In macros alsways srround the variables with parenthesis
#define GOOD_SQUARE(x) (x) * (x)
int main(int argc, char const *argv[])
{
printf("BAD_SQUARE(2) = : %d \n", BAD_SQUARE(2) );
printf("GOOD_SQUARE(2) = : %d \n", GOOD_SQUARE(2) );
printf("BAD_SQUARE(2+1) = : %d ; because the macro will be \
subsituted as 2 + 1 * 2 + 1 \n", BAD_SQUARE(2+1) );
printf("GOOD_SQUARE(2+1) = : %d ; because the macro will be \
subsituted as (2 + 1) * (2 + 1) \n", GOOD_SQUARE(2+1) );
return 0;
}
Just enclose each and every argument in the macro expansion into parentheses.
#define SQR(x) ((x)*(x))
This will work for whatever argument or value you pass.

I can not understand Macro function`s result in C language

--
Hello,
I can`t understand why "#define max(a,b) (a>b)?(a):(b)" does not work that i expected.
#include<cstdio>
#define max(a,b) (a>b)?(a):(b)
int main(void){
printf("%d\n",max(3,5)); // result = 5 (work correctly)
int a = 3 + max(3,5);
printf("%d\n",a); // result = 3 (work incorrect and i don`t know why..)
}
i can`t why variable + macro does not work.
but, In this case "#define max(a,b) ((a>b)?(a):(b))" work correctly. even that var + macro situation.
plz anybody clarify this.. thx.
When you have this:
#define max(a,b) (a>b)?(a):(b)
And you write this:
int a = 3 + max(3,5);
That expands to:
int a = 3 + (a>b)?(3):(5)
Because + has a higher operator precendence than ?, this is effectively:
int a = (3 + (a>b)) ? (3) : (5)
And since 3 + (a>b) is always going to evaluate to a true-ish value, the result will always be 3.
By putting the whole expansion in parentheses:
#define max(a,b) ((a>b)?(a):(b))
You get instead:
int a = 3 + ((a>b)?(3):(5))
Because the outer parentheses group the ternary operator expression, you get the result you expect.
Note that as #zwol writes in a comment, you should actually write your macro like:
#define max(a,b) (((a)>(b))?(a):(b))
The extra parentheses around a and b in (a)>(b) protect against exactly this sort of operator precedence problem.
Operator precedence. I get a warning with clang.
test.cc:7:15: warning: operator '?:' has lower precedence than '+'; '+' will be evaluated first [-Wparentheses]
int a = 3 + max(3,5);
Easy to fix with parenthesis.
#define max(a,b) ((a>b)?(a):(b))

Incorrect multiplication of integers in C

A C-coded S-function in Simulink was showing incorrect behaviour and I have managed to narrow down the problem to an incorrect multiplication of integers.
At the start of the code, I have something like:
#define NRBF 21
#define NRBF1 NRBF+1
Then, in a function in the script I have:
void function_name(SimStruct *S, const int_T a)
{
...
int_T base;
base = a*NRBF1;
printf("%i\t", a);
printf("%i\t", NRBF1);
printf("%i\n", base);
..
}
Now, if a=0, NRBF=21, I have (instead of base=0)
0 22 1
If a=1, NRBF=21, I have (as expected base=22)
1 22 22
If a=2, NRBF=21, I have (instead of base=44)
2 22 43
Now, I must say I am a bit baffled. I tried to change the line of the multiplication to
base = a* (int_T)NRBF1;
but it does not solve the problem.
Any help would be greatly appreciated! Thank you!
The problem is here:
You define your macros like this:
#define NRBF 21
#define NRBF1 NRBF+1
When you write this:
base = a*NRBF1;
The preprocessor replaces NRBF1 textually with 21+1 which results in this:
base = a*21+1;
but you intended this:
base = a*(21+1);
Therefore you need to define your macro like this:
#define NRBF1 (NRBF+1)
With the macro expanded, the line looks like:
base = a*NRBF+1;
For a equal to 0, the expression is 0 * 21 + 1 which is 1.
For a equal to 2, the expression is 2 * 21 + 1 which is 43.
The solution is to put parentheses in the macro definition:
#define NRBF1 (NRBF + 1)
This is a good rule for any macro with an expression as its right-hand side.
Remember that macros are just text-substituted into the code.
It's basically calculating alright
0*21+1 = 1
The macro is expanded but the * has precedence over +. That's why this happens.
A more detail explanation would be
#define NRBF 21
#define NRBF1 NRBF+1
So what is going on
base = a*NRBF1;
or
base = a*NRBF+1
Now when a = 0 then base = 1
when a = 1 then base = 21+1 ...so on.
Correct way would be to wrap it aropund parentheses.
#define NRBF1 (NRBF+1)
Some more pitfalls:
That when you add a macro like this #define SQR(X) X*X
For some example like this where same precedence operators are there next to next then it will be problematic.
int i = 100/SQR(10);
Then it will be expanded to
int i = 100/10*10
Now same precedence operators are here executed left to right.
So it will result in i=100.
Solution same #define SQR(X) (X*X)
Also when passing an expression like this SQR(i+1) then it will be expanded to i+1*i+1=2*i+1. So a bit more correct would be
#define SQR(X) ((X)*(X))
Even with that you wouldn't be able to avoid few things if you forget one thing macro just expands - it does nothing more.
You can't use macro like this
SQR(i++) which will be expanded to ((i++)*(i++)). So you are increasing the i twice which is what you didn't mean. Moreover this will result in undefined behavior.
the define doesn't create a single value 22 but the expression 21 + 1. I wonder whether your problems go away if you change your second #define to
#define NBRF1 (NBRF + 1)

Macro usage in C?

I am newbie to C and trying to understand the MACRO expansion logic in C.
I wonder why the first approach is not working but second works as expected.
First approach
#include <stdio.h>
#define square(x) x*x
int main()
{
int x = 36/square(6); // Expended as 36/6*6
printf("%d", x);
return 0;
}
// Output: 36
Second approach
#include <stdio.h>
#define square(x) x*x
int main()
{
int x = square(6)/36; // Expended as 6*6/36
printf("%d", x);
return 0;
}
// Output: 1
Could someone explain me the difference ?
square(6)/36
expands to
6*6/36
which is equivalent to
(6*6)/36
and obviously equals 1.
Even though this is apparently for understanding macros and you may be aware of that, one suggestion:
macros involving operators should be surrounded by parantheses!
First expansion
36/6*6
Using the rules of precedence and left to right http://en.cppreference.com/w/c/language/operator_precedence works it out as
36/6 * 6 -> (36 / 6) * 6 -> 6 * 6 -> 36
Second expansion
6*6/36 -> (6 * 6)/36 -> 36 / 36 -> 1
Using the precedence/left to right rules above.
Sorry for the link - Did not want the cutter. Multiplication has higher precedence than division
Your macro should be defined as
#define square(x) ((x)*(x))
It is necessary to enclose the x's in parenthesis to prevent any surprises about operator precedence. The outer parenthesis are for the same reason.
Please note that this macro even as corrected above will not work if the parameter is a self-modifying expression. So you may want to consider putting it in all-uppercase or something to alert the user of the macro that it will not behave equivalently to a function call.
The reason your expansion of 36/square(6) does not work as you expect is because of its expansion.
36/square(6)
36/6*6
6*6 <-- 36/6 evaluated
36 <-- 6*6 evaluated
The corrected macro would be expanded thus
36/((6)*(6))
36/(36)
1
Which is the answer you would expect. Also note that 5+1 would also work as an argument because of the inner parenthesis but y++ would not behave as you would expect if reading the macro as a function, hence the reason I recommend naming it SQUARE to alert the user that this is a macro not a function.
Macros only behave as functions if each of their parameters appears exactly once and the syntax is otherwise like an expression (i.e. no {}'s). Also the user cannot pass a pointer to a macro as they can to a function.
Your question is a good illustration of the kind of problem that arise with macros:
36/square(6) expands to 36/6*6, which is parsed according to the C grammar as
(36 / 6) * 6
evaluating to 36.
If you had defined the macro as
#define square(x) ((x)*(x))
Both expressions would be equivalent and evaluate to 1.
Yet there is still a problem with this macro:
square(i++) expands as ((i++) * (i++)).
Evaluating i++ twice in the same expression is undefined behavior.

The need for parentheses in macros in C [duplicate]

This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 5 years ago.
I tried to play with the definition of the macro SQR in the following code:
#define SQR(x) (x*x)
int main()
{
int a, b=3;
a = SQR(b+5); // Ideally should be replaced with (3+5*5+3), though not sure.
printf("%d\n",a);
return 0;
}
It prints 23. If I change the macro definition to SQR(x) ((x)*(x)) then the output is as expected, 64. I know that a call to a macro in C replaces the call with the definition of the macro, but I still can’t understand, how it calculated 23.
Pre-processor macros perform text-replacement before the code is compiled so
SQR(b+5) translates to
(b+5*b+5) = (6b+5) = 6*3+5 = 23
Regular function calls would calculate the value of the parameter (b+3) before passing it to the function, but since a macro is pre-compiled replacement, the algebraic order of operations becomes very important.
Consider the macro replacement using this macro:
#define SQR(x) (x*x)
Using b+5 as the argument. Do the replacement yourself. In your code, SQR(b+5) will become: (b+5*b+5), or (3+5*3+5). Now remember your operator precedence rules: * before +. So this is evaluated as: (3+15+5), or 23.
The second version of the macro:
#define SQR(x) ((x) * (x))
Is correct, because you're using the parens to sheild your macro arguments from the effects of operator precedence.
This page explaining operator preference for C has a nice chart. Here's the relevant section of the C11 reference document.
The thing to remember here is that you should get in the habit of always shielding any arguments in your macros, using parens.
Because (3+5*3+5 == 23).
Whereas ((3+5)*(3+5)) == 64.
The best way to do this is not to use a macro:
inline int SQR(int x) { return x*x; }
Or simply write x*x.
The macro expands to
a = b+5*b+5;
i.e.
a = b + (5*b) + 5;
So 23.
After preprocessing, SQR(b+5) will be expanded to (b+5*b+5). This is obviously not correct.
There are two common errors in the definition of SQR:
do not enclose arguments of macro in parentheses in the macro body, so if those arguments are expressions, operators with different precedences in those expressions may cause problem. Here is a version that fixed this problem
#define SQR(x) ((x)*(x))
evaluate arguments of macro more than once, so if those arguments are expressions that have side effect, those side effect could be taken more than once. For example, consider the result of SQR(++x).
By using GCC typeof extension, this problem can be fixed like this
#define SQR(x) ({ typeof (x) _x = (x); _x * _x; })
Both of these problems could be fixed by replacing that macro with an inline function
inline int SQR(x) { return x * x; }
This requires GCC inline extension or C99, See 6.40 An Inline Function is As Fast As a Macro.
A macro is just a straight text substitution. After preprocessing, your code looks like:
int main()
{
int a, b=3;
a = b+5*b+5;
printf("%d\n",a);
return 0;
}
Multiplication has a higher operator precedence than addition, so it's done before the two additions when calculating the value for a. Adding parentheses to your macro definition fixes the problem by making it:
int main()
{
int a, b=3;
a = (b+5)*(b+5);
printf("%d\n",a);
return 0;
}
The parenthesized operations are evaluated before the multiplication, so the additions happen first now, and you get the a = 64 result that you expect.
Because Macros are just string replacement and it is happens before the completion process. The compiler will not have the chance to see the Macro variable and its value. For example: If a macro is defined as
#define BAD_SQUARE(x) x * x
and called like this
BAD_SQUARE(2+1)
the compiler will see this
2 + 1 * 2 + 1
which will result in, maybe, unexpected result of
5
To correct this behavior, you should always surround the macro-variables with parenthesis, such as
#define GOOD_SQUARE(x) (x) * (x)
when this macro is called, for example ,like this
GOOD_SQUARE(2+1)
the compiler will see this
(2 + 1) * (2 + 1)
which will result in
9
Additionally, Here is a full example to further illustrate the point
#include <stdio.h>
#define BAD_SQUARE(x) x * x
// In macros alsways srround the variables with parenthesis
#define GOOD_SQUARE(x) (x) * (x)
int main(int argc, char const *argv[])
{
printf("BAD_SQUARE(2) = : %d \n", BAD_SQUARE(2) );
printf("GOOD_SQUARE(2) = : %d \n", GOOD_SQUARE(2) );
printf("BAD_SQUARE(2+1) = : %d ; because the macro will be \
subsituted as 2 + 1 * 2 + 1 \n", BAD_SQUARE(2+1) );
printf("GOOD_SQUARE(2+1) = : %d ; because the macro will be \
subsituted as (2 + 1) * (2 + 1) \n", GOOD_SQUARE(2+1) );
return 0;
}
Just enclose each and every argument in the macro expansion into parentheses.
#define SQR(x) ((x)*(x))
This will work for whatever argument or value you pass.

Resources