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

--
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))

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.

Preprocessors in C [duplicate]

This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 3 years ago.
I have a doubt in the output of a code. The code uses preprocessors of c language. The code is given below,
#include <stdio.h>
#define sqr(x) x*x
int main() {
int x = 16/sqr(4);
printf("%d", x);
}
The result of sqr(4) is equal to 16. So, the value in x must be 1 (16/16=1). But if I print the value of x, the output is 16. Please explain me why this is happening.
I am attaching the screenshot of output pane.
Output Window
In C, macros are filled into your code upon compilation. Let's consider what happens in your case:
Your macro is:
#define sqr(x) x*x
When it gets filled into this:
int x = 16/sqr(4);
You would get:
int x = 16/4*4;
Operator precedence being equal for / and *, this gets evaluated as (16/4)*4 = 16, that is, from left to right.
However, if your macro were this:
#define sqr(x) (x*x)
then you would get:
int x = 16/(4*4);
... and that reduces to 1.
However, when the argument for your macro is more complex than a simple number, e.g. 2+3, it would still go wrong. A better macro is:
#define sqr(x) ((x)*(x))
After macro replaces your expression, it becomes int x = 16/4*4 and is evaluated accordingly. i.e. (16/4)*4 which is 16.
sqr(x) doesn't calculate 4*4, it is not a function.
You are actually doing 16/4*4 which is in fact 16.
You can change your define to
#define sqr(x) (x*x)
Now you will be doing 16/(4*4).
It is expanded to
int x = 16/4*4;
Something like
#define sqr(x) ((x) * (x))
would be more safe, precedence and associativity-wise, still works poorly in expressions like sqr(a++). Inline functions are simpler to use in this context.

Using Parentheses in Define Preprocessor Statements

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.

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.

Using macro results in incorrect output when used as part of a larger math expression - why does this happen?

This is a normal C routine program which i found out in some question bank. It is shown below:
#define CUBE(p) p*p*p
main()
{
int k;
k = 27 / CUBE(3);
printf("%d", k);
}
As per my understanding and knowledge the value of K should be 1 as CUBE(3) would be replaced by 3*3*3 during preprocessing and after the subsequent compilation it would be giving the value of 1, but instead it has shown the value of 81 which has made me curious to know how it happened.
Can anyone please justify the answer of 81 to this question above.
The preprocessor merely substitutes
CUBE(3)
with
3*3*3
So you end up with:
k=27/3*3*3
Which, evaluated left-to-right with operator precedence, is in fact 81.
If you add parenthesees around the macro, you should find the results are correct:
#define CUBE(p) (p*p*p)
It would be even better to surround each instance of p with parenthesees as well, as in:
#define CUBE(p) ((p)*(p)*(p))
Which will allow you to pass expressions to the macro correctly (for example, 1 + 2).
Because of operator precedence 27/3*3*3 = 81
You could use instead:
inline int cube(int p) { return p*p*p; }
Preprocessors should be parenthesized properly. Replace it with
#define CUBE(p) ((p)*(p)*(p))
and see.
C macros do textual substitution (i.e. it's equivalent to copying and pasting code). So your code goes from:
k=27/CUBE(3);
to
k=27/3*3*3;
Division and multiplication have the same precedence and have left-to-right associativity, so this is parsed as:
k=((27/3)*3)*3;
which is 9 * 3 * 3 = 81.
This is why C macros should always be defined with liberal use of parentheses:
#define CUBE(p) ((p) * (p) * (p))
For more information, see http://c-faq.com/cpp/safemacros.html from the comp.lang.c FAQ.
Your macro is not protected. Try
#define CUBE(p) ((p)*(p)*(p))
The current macro was expanded to
k=27/3*3*3
which is ((27/3)*3)*3
Because macros are a textual substitution, that works out to:
k = 27 / 3 * 3 * 3;
Since multiplication and division happen left to right, that works out to:
k = ((27 / 3) * 3) * 3;
So, you want to change that in two ways:
#define CUBE(p) ((p)*(p)*(p))
The outer parentheses cause the multiplications to be done before any other operations.
The parentheses around the individual p's are for the case where you do:
CUBE(1 + 2);
Without those inner parentheses, operator precedence will trip you up.
k=27/CUBE(3); => k=27/3 * 3 * 3;
Do you see it? CUBE should be defined like this instead:
#define CUBE(p) ((p)*(p)*(p))
When you do macros, you have to be careful about how you place parentheses. In this case, you don't have any, so the expression becomes 27/3*3*3, which by the precedence rules of / and * becomes (27/3)*3*3.
27/3*3*3 = 9*3*3 = 81 ?
Both / and * operators have the same precedence. To execure 3*3*3 first, you shoudl enclose them in parenthesis.
#include <stdio.h>
#define CUBE(p) p*p*p
int
main ()
{
int k;
k=27/(CUBE(3));
printf("%d",k);
return 0;
}
#define CUBE(p) p*p*p
main()
{
int k;
k=27/CUBE(3);
printf("%d",k);
}
As per my understanding and knowledge the value of K should be 1 as CUBE(3) would be replaced by 3*3*3 during preprocessing
YES
and after the subsequent compilation it would be giving the value of 1,but instead it has shown the value of 81 which has made me curious to know how it happenned.
NO,
k= 27/3*3*3
=(((27/3)*3)*3) (The precedence of `*` and `/` are same but the associativity is from left to right)
=((9*3)*3) =81
Replace #define CUBE(p) p*p*p with #define CUBE(p) ((p)*(p)*(p))
its the way in which the associativity and precedence of operators is implemented.
when the expression is expanded it becomes
27/3*3*3 and not 27/(3*3*3)
now, division and multiplication both have the same precedence in C but the associativity is left to right for both.
so it can be shown as :
(27/3)*3*3 which in turn equals (9*3)*3 = 81
also, if u remember the old arithmetic rule of BODMAS(Bracket Off Division Multiplication Addition Subtraction), this is the order of precedence, then we do division first and then multiplication.
so again we get answer as 81 for 27/3*3*3.
Hi answer for this is:81
Explanation:
In step k=27/cube(3)
cube(3) is replaced by 3*3*3 by preprocessor.then above statement becomes as k=27/3*3*3
in that 27/3 expression is evaluated by c compiler(operator precedence)
the result is(27/3) :9
the statement k=27/3*3*3 becomes as k=9*3*3;
the result for above statement is 81:

Resources