I'm quite confusing about this:
#define prod(x,y) x*y
The following function call prints 11 in the console:
printf("%d",prod(1+2,3+4));
But when I use prod(x,y) as a function returning x*y, it returns 21.
Why the results are different? I thought #define should give prod(x,y) = x*y.
Operator precedence is biting you.
With
#define prod(x,y) x*y
the line
printf("%d",prod(1+2,3+4));
gets expanded to
printf("%d",1+2*3+4);
Note that * has higher precedence than +, so this is evaluated as 1 + (2 * 3) + 4 or 11.
Solution:
Surrround the parameters with parenthesis in your #define:
#define prod(x,y) ((x)*(y))
The line will now be expanded to:
printf("%d",((1+2)*(3+4)));
The purpose of the extra set of parenthesis around the entire expression is to make the expression work as you want when used in conjunction with an operator where evaluation order matters.
prod(4,3)/prod(1,2)) gets expanded to ((4)*(3))/((1)*(2)) or 6. Without the outer parenthesis the expansion would be (4)*(3)/(1)*(2) or 24.
According to your macro, prod(1+2,3+4) is expanded to 1+2*3+4 which equals to 11. Use parens to fix it:
#define prod(x, y) ((x)*(y))
With your definition of
#define prod(x,y) x*y
The line
printf("%d",prod(1+2,3+4));
becomes
printf("%d",1+2*3+4);
which will evaluate to
printf("%d",1+6+4);
yielding
11
A function evaluates things differently. With the function
int prod(int x, int y) { return x*y; }
the call
printf("%d",prod(1+2,3+4));
will have to collapse (evaluate) the parameters before they can be passed. This is because C is "pass by value" in it's parameter handling style. Even pointers, which are technically references are turned into values representing the reference and those values are passed. So the call reduces to
printf("%d",prod(3,7));
which inside the function becomes
return 3*7;
or
return 21
There's a valueable lesson here. Macros don't understand the language. They are just text substitutions, and they will not honor types, operator precedence, or any other language element you've taken the time to learn. Basically the macro language is a different-than-C language, and a much more primitive one than C.
Related
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.
Here are 2 snippets of code, one is a macro and one is a function. They seem to do the same thing but after running them it seems that they exhibit different behavior and I don't know why. Could anyone help me please? Thanks!
#define ROL(a, offset) ((((Lane)a) << ((offset) % LANE_BIT_SIZE)) ^ (((Lane)a) >> (LANE_BIT_SIZE-((offset) % LANE_BIT_SIZE))))
Lane rotateLeft(Lane lane, int rotateCount)
{
return ((Lane)lane << (rotateCount % LANE_BIT_SIZE)) ^ ((Lane)lane >> (LANE_BIT_SIZE - (rotateCount % LANE_BIT_SIZE))) ;
}
Note: the Lane type is just an unsigned int and LANE_BIT_SIZE is a number representing the size of Lane in terms of No. of bits.
Think of using a macro as substituting the body of the macro into the place you're using it.
As an example, suppose you were to define a macro: #define quadruple(a) ((a) * (a) * (a) * (a))
... then you were to use that macro like so:
int main(void) {
int x = 1;
printf("%d\n", quadruple(x++));
}
What would you expect to happen here? Substituting the macro into the code results in:
int main(void) {
int x = 1;
printf("%d\n", ((x++) * (x++) * (x++) * (x++)));
}
As it turns out, this code uses undefined behaviour because it modifies x multiple times in the same expression. That's no good! Do you suppose this could account for your difference in behaviour?
one is macro and other one is function, the simple understanding gives difference in the way it will be called.
As in case of function CONTEXT SWITCHING will be there, you code flow will be changed to the calling function and will return eventually so there will be very small delay in execution when compared to MACRO.
other than that there should not be any other difference.
Please try by declaring the function as inline function then both should be same.
Lane may be promoted to a type with more bits, e.g. when it's an unsigned char or unsigned short, or when it is used in a larger assignment with mixed types. The <<operation will then shift the higher bits into the additional bits of the larger type.
With the function call these bits will be just cut off, because it returns a Lane, while the macro gives you the full result of the promoted type, including the additional bits - beside the other problems of macros, like multiple evaluations of the arguments.
Here are 2 snippets of code, one is a macro and one is a function.
They seem to do the same thing but after running them it seems that
they exhibit different behavior and I don't know why.
No they are doing the same thing.
ROL(a, offset); //does a*(2^offset)
rotateLeft(Lane lane, int rotateCount); //does lane*(2^rotateCount)
The only difference is that ROL is implemented through a macro , and rotateLeft() is a function.
Differences between Macros and functions
Macros are executed in the preprocessing stage of the compiler ,
whereas function executes , when it is called at runtime execution.
As a result Macros execute faster than functions , but when called
multiple times , the macro text is substitutes same code redundantly, and they end up consuming more "code" memory than an implementation using functions.
Unlike a function , there is no Type Enforcement in a macro.
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.
For example:
#define FOO(x) (printf(x))
and
#define FOO(x) {printf(x)}
It seems that both are viable for preprocessing, but which is better?
If you're treating the macro as an expression, use the () form.
If you're treating it as a command (and never as an expression) then use the {} form. Or rather, use the do{}while(0) form as that has fewer substitution hazards when used near keywords like if:
#define FOO(x) do { \
printf(x); \
} while(0)
Parentheses () are used to enforce correct evaluation regardless of operator precedence, so that you hopefully won't get any nasty side effects when the macro is expanded.
Braces {} are used to make the macro a C block statement, although the canonical way to do this is:
#define FOO(x) \
do { \
... stuff ... \
} while (0)
Note that gcc provides an extension to the C language which makes it possible to return a value from a block - the last expression evaluated will be the value returned if the block is used as part of an expression.
The purpose of using parens in a macro is to control precedence when the macro is expanded. Consider:
#define X( a, b ) a * b
if the macro is used like this
X( 1 + 2, 3 )
we would presumably like the answer to be 9, but what we get on expansion is:
1 + 2 * 3
giving us 7. To avoid this kind of thing, we should have written the macro as:
#define X( a, b ) ((a) * (b))
If precedence is not an issue, brackets either type are not absolutely required, though braces may be needed depending on the ,macros semantics - if for example you want to create a local variable,
If you will ever need FOO(x) inside an expression, then you cannot use the {} form. For example:
result = FOO(some_variable);
or
if (FOO(some_variable))
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: