This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 4 years ago.
I am new to c language. I just wanted to know why is my macro not working properly. It is giving me output as 13 where as my expected output is 24.?
#include<stdio.h>
#define mult(a,b) a*b
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
mult(x+2,y-1) expands to x +2 * y -1 that is equals to 4 + 2 * 5 -1 gives output: 13.
You might be expecting answer (4 + 2) * (5 -1) = 6 * 4 = 24. To make it expand like this you should write parenthesize macro as #H2Co3 also suggesting:
#define mult(a,b) ((a)*(b))
Read aslo: So, what's wrong with using macros? by Bjarne Stroustrup.
This is because C macros are simple textual substitutions, the macro writer must be sure to insert parentheses around every macro variable when it is substituted, and around the macro expansion itself, to prevent the resulting expansion from taking on new meanings.
If you observe your program: mult(a, b) is defined as a * b
mult(x + 2, y - 1) = x + 2 * y - 1 = 4 + 2 * 5 - 1 = 4 + 10 - 1 = 13
The Correct way would be:
mult(a, b) ((a) * (b))
Use parentheses in the macro definition
#include<stdio.h>
#define mult(a,b) ((a)*(b))
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
This is because different arithmetic operators have different precedence levels. Hence always use parentheses while defining the macro.
Because it replaces the arguments literally:
mult(x+2,y-1) --> mult(4+2,5-1) --> 4 + 2*5 - 1 --> 13
Try changing the define to:
#define mult(a,b) (a)*(b)
In this case the result after pre-processing is this:
int main()
{
int x=4,y=5;
printf("%d",(x+2)*(y-1));
return 0;
}
This will solve the problem but it's still not the best way to do it.
#define mult(a,b) ((a)*(b))
This version is considered as good practice because in other types of situation the first one would fail. See the bellow example:
#include<stdio.h>
#define add(a,b) (a)+(b)
int main()
{
int x=4,y=5;
printf("%d",add(x+2,y-1)*add(x+2,y-1));
return 0;
}
In this case it would give an incorrect answer because it is translated by the pre-processor to the fallowing:
int main()
{
int x=4,y=5;
printf("%d",(x+2)+(y-1)*(x+2)+(y-1));
return 0;
}
printing 34 instead of 100.
For the ((a)+(b)) version it would translate to:
int main()
{
int x=4,y=5;
printf("%d",((x+2)+(y-1))*((x+2)+(y-1)));
return 0;
}
giving a correct answer.
Related
I was just going through certain code which are frequently asked in interviews. I came up with certain questions, if anyone can help me regarding this?
I am totally confused on this now,
#include <stdio.h>
#include <conio.h>
#define square(x) x*x
main()
{
int i, j;
i = 4/square(4);
j = 64/square(4);
printf("\n %d", i);
printf("\n %d", j);
printf("\n %d", square(4));
getch();
}
The output is:
4
64
16
I am wondering, why did square(4) return 1 when I divided it? I mean, how can I get the value 4 and 64 when I divide it, but when used directly I get 16!!?
square is under-parenthesized: it expands textually, so
#define square(x) x*x
...
i=4/square(4);
means
i=4/4*4;
which groups as (4/4) * 4. To fix, add parentheses:
#define square(x) ((x)*(x))
Still a very iffy #define as it evaluates x twice, so square(somefun()) calls the function twice and does not therefore necessarily compute a square but rather the product of the two successive calls, of course;-).
When you write i=4/square(4), the preprocessor expands that to i = 4 / 4 * 4.
Because C groups operations from left to right, the compiler interprets that as i = (4 / 4) * 4, which is equivalent to 1 * 4.
You need to add parentheses, like this:
#define square(x) ((x)*(x))
This way, i=4/square(4) turns into i = 4 / ((4) * (4)).
You need the additional parentheses around x in case you write square(1 + 1), which would otherwise turn into 1 + 1 * 1 + 1, which is evaluated as 1 + (1 * 1) + 1, or 3.
i=4/square(4);
expands to
i=4/4*4;
which equivalent to
i=(4/4)*4;
Operator precedence is hurting you.
The macro is expanded by the pre-processor such that
i=4/4*4;
j=64/4*4;
which is equivalent to:
i=(4/4)*4;
j=(64/4)*4;
That's because the compiler replaces it with:
i=4/4*4;
j=64/4*4;
i = (4/4)*4 = 1*4 = 4.
j = (64/4)*4 = 16*4 = 64.
j = 4/square(4) == 4/4*4 == 1*4 == 4
Manually expand the macro in the code, and it will be clear. That is, replace all the square(x) with exactly x*x, in particular don't add any parentheses.
define is just a text macro
main()
{
int i,j;
i=4/ 4 * 4; // 1 * 4
j=64/4 * 4; // 16 * 4
printf("\n %d",i);
printf("\n %d",j);
printf("\n %d",square(4));
getch();
}
It's a macro! So it returns exactly what it substitutes.
i = 4/4*4; Which is 4...
j = 64/4*4; Which is 16...
Try this for your macro:
#define square(x) ((x)*(x))
Because of operator precedence in the expression after the preprocessor - you'll need to write
#define square(x) (x*x)
As the other answers say, you're getting burned by operator precedence. Change your square macro to this:
#define square(x) (x*x)
and it'll work the way you expect.
This question already has answers here:
Preprocessor macro in C
(3 answers)
Closed 5 years ago.
I am learning C in depth. But I am not getting this program. Somebody, please tell me how the output of the below program is m=2, n=3
#include <stdio.h>
#define MAX(a,b) a>b ? a:b
int main()
{
int m,n;
m=3+MAX(2,3);
n=2*MAX(3,2);
printf("m=%d, n=%d\n",m,n);
return 0;
}
This is why parenthesis in macro definitions are important.
A macro does simple text substitution. So when you do this:
m=3+MAX(2,3);
It expands to this:
m=3+2>3 ? 2:3
With the implicit parenthesis:
m = ((3+2)>3) ? 2:3
Which is probably not what you want.
You need to put parenthesis around the entire macro as well as around each argument wherever it is used:
#define MAX(a,b) ((a)>(b) ? (a) : (b))
This will then expand to:
m = 3 + ((2)>(3) ? (2):(3))
Also note that with a macro like this you open yourself up to side effects of one of the operands. For example, if you did this:
int a=2, b=3;
m = MAX(a++,b);
You would get:
int a=2, b=3;
m = ((a++) > (b) ? (a++) : (b));
This invokes undefined behavior because it attempts to modify a more than once in an expression without a sequence point.
This is what happens in your case:
int main() {
int m,n;
m=3+2>3 ? 2:3; //(3+2)>3 ? 2 : 3 = 2
n=2*3>2 ? 3:2; //(2*3)>2 ? 3 : 2 = 3
printf("m=%d, n=%d\n",m,n);
return 0;
}
If you rewrite your defined to #define MAX(a,b) ((a)>(b) ? (a):(b))
then you will have desired output as it will be evaluated to:
//Correct way with parenthesis
int main() {
int m,n;
m=3+((2)>(3) ? (2):(3)); //6
n=2*((3)>(2) ? (3):(2)); //6
printf("m=%d, n=%d\n",m,n);
return 0;
}
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Unintended multiple evaluation of parameter in macro
(1 answer)
Closed 6 years ago.
#include <stdio.h>
// 2.1
#define subm(a,b) (a - b)
#define cubem(a) (a * a * a)
#define minm minf
#define oddm oddf
//---------------------------Given Code------------------------------------
int subf(int a, int b) {
return a - b;
}
int cubef(int a) {
return a * a * a;
}
int minf(int a, int b) {
if (a <= b) {
return a;
} else {
return b;
}
}
int oddf(int a) {
if (a % 2 == 0) {
return 0;
} else {
return 1;
}
}
//----------------------------Given Code----------------------------------
// 2.2
int main() {
int a = 5;
int b = 7;
subf(a,b);printf("subf = %d\n", subf(a,b));
subm(a,b);printf("subm = %d\n", subm(a,b));
subf(a++,b--);printf("subf = %d\n", subf(a++,b--));
subm(a++,b--);printf("subm = %d\n", subm(a++,b--));
cubef(a);printf("cubef = %d\n", cubef(a));
cubem(a);printf("cubem = %d\n", cubem(a));
cubef(--a);printf("cubef = %d\n", cubef(--a));
cubem(--a);printf("cubem = %d\n", cubem(--a));
minf(a,b);printf("minf = %d\n", minf(a,b));
minm(a,b);printf("minm = %d\n", minm(a,b));
minf(--a,--b);printf("minf = %d\n", minf(--a,--b));
minm(--a,--b);printf("minm = %d\n", minm(--a,--b));
oddf(a);printf("oddf = %d\n", oddf(a));
oddm(a);printf("oddm = %d\n", oddm(a));
oddf(a++);printf("oddf = %d\n", oddf(a++));
oddm(a++);printf("oddm = %d\n", oddm(a++));
}
I'm having some trouble with putting the functions inside the macro. My professor wants us to understand how macro and functions are processed. The way I'm doing it is basically as you see here, but it's not working correctly, or at least
#define cubem(a) (a * a * a)
Is generating an error and I don't know why. Can someone please help?
edit: the error is as shown
hw02q2.c:42:31: warning: multiple unsequenced modifications to 'a'
[-Wunsequenced]
printf("cubem = %d\n", cubem(--a));
^~
hw02q2.c:4:19: note: expanded from macro 'cubem'
#define cubem(a) (a * a * a)
The reason is that
#define cubem(a) (a * a * a)
/* and later using it .... */
printf("cubem = %d\n", cubem(--a));
does text substitution, and produces
printf("cubem = %d\n", (--a * --a * --a));
which modifies a three times in one statement. That is undefined behaviour according to the C standard.
In comparison,
int cubef(int a) {
return a * a * a;
}
/* and later */
printf("cubef = %d\n", cubef(--a));
evaluates --a once, passes the resultant value to cubef().
If you really want to "put a function in a macro", then do something like
#define cubem(a) cubef(a)
which causes the statement
printf("cubem = %d\n", cubem(--a));
to become
printf("cubem = %d\n", cubef(--a));
The problem with this is that it does not work with a macro that uses its argument more than once. For example
int sq(int a) {return a * a;}
#define cubesq(a) (a * sq(a)) /* uses a more than once
causes
printf("cubesq = %d\n", cubesq(--a));
to be seen by the compiler as
printf("cubem = %d\n", (--a * cubesq(--a));
which, again, modifies a more once and causes undefined behaviour.
The reason is simple: the preprocessor does TEXT SUBSTITUTION and modifies source code seen by a later phase of the compiler.
Instead of "trying to put a function inside a macro", simply don't use macros. Write functions. Use functions. Or use macros, but respect their limitations (i.e. they don't work like functions do, even if they look like functions).
C Macros perform textual substitution: each instance is replaced with the macro definition with the macro parameter names replaced with the exact text of the instance arguments.
Your cubem macro defined as #define cubem(a) (a * a * a) will expand this way:
cubem(--a) -> (--a * --a * --a)
Modifying a multiple times within the same expression has undefined behavior. You cannot work around this problem portably. You could try using compiler extensions if you are familiar enough and don't mind relying on non-portable constructions.
The correct way to implement the function and have it expand inline is via an inline function definition:
static inline cubem(int a) { return a * a * a; }
Note also that the macro has other problems:
cubem(1 + 1) expands to (1 + 1 * 1 + 1 * 1 + 1) which evaluates to 4 instead of 8.
To avoid this problem, all macro arguments should be parenthesized:
#define cubem(a) ((a) * (a) * (a))
But this definition still does not support arguments with side effects:
cubem(getchar()) will read 3 bytes from standard input.
Since you invoke cubem(--a) like this, your cubem definition should avoid side effect.
#define cubem(a) \
({ \
typeof(a) dummy_a = (a); \
dummy_a * dummy_a * dummy_a; \
})
Above is a gcc c extension, read the gcc document, chapter
Statements and Declarations in Expressions
i expect the output (or value of silly) to be 36. but what i get is 14. this is fixed when i add parentheses: #define THING (4+2).
but i still want to know what is happening when there are no parentheses and why im getting an output of 14
.
the following is my code:
#include <stdio.h>
#include <stdlib.h>
#define THING 4+2
int main(void)
{
int silly = THING * THING;
printf("%d", silly);
return EXIT_SUCCESS;
}
THING*THING = 4+2*4+2 = 4+(2*4)+2 // because of higher precedence of * than +
= 4+8+2 = 14.
Do remember that MACROs are exactly replaced(substituted) into the code.
The macro is literally inserted in place of THING.
THING * THING is 4+2 * 4+2 is 4 + (2 * 4) + 2 which is 14.
If you want the result to be 36 than you need to define your macro wrapped in parenthesis:
#define THING (4 + 2)
Because macros are (almost) the same as text replacement. int silly = THING * THING; is converted by the preprocessor to int silly = 4+2 * 4+2;, and order of operations means that's processed as 4 + (2 * 4) + 2, not (4 + 2) * (4+ 2).
You need parentheses because order of operations is interfering. Macros just replace text, and so without parentheses, the operations are not being evaluated in the order expected.
THING * THING ----> 4 + 2 * 4 + 2 = 14
So, once you use parentheses, this fixes it because it becomes:
THING * THING ----> (4 + 2) * (4 + 2) = 36
This is explained in this preprocessor tutorial.
Why is the answer for the below code 16? Can anybody explain the working of this program?
#define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
If we write the same code like below, then the answer is 4:
//the ans is 4 why?
#include<stdio.h>
#include<conio.h>
#define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}
The preprocessor just replaces the text, exactly as written.
So, the macro call SQUARE(2) becomes literally 2*2.
In your case, that means the whole expression becomes 16/2*2, which because of C's precedence rules evaluates to (16/2)*2, i.e. 16.
Macros should always be enclosed in parenthesis, and have each argument enclosed as well.
If we do that, we get:
#define SQUARE(n) ((n) * (n))
which replaces to 16/((2) * (2)), which evaluates as 16/4, i.e. 4.
The parens around each argument makes things like SQUARE(1+1) work as expected, without them a call such as 16/SQUARE(1+1) would become 16/(1+1*1+1) which is 16/3, i.e. not at all what you'd want.
Order of operations. Your expression is evaluating to:
j = 16 / 2 * 2
which equals 16. Make it:
#define SQUARE(n) (n*n)
which will force the square to be evaluated first.
You need to define your macro with insulating parentheses, like so:
#define SQUARE(n) ((n)*(n))
Otherwise
j = 16/SQUARE(2);
expands to
j = 16 / 2 * 2; which is equivalent to (16 / 2) * 2
When what you want is
j = 16 / (2 * 2);
1. When using macros that are to be used as expressions, you should parenthesise the whole macro body.
This prevents erroneous expansions like:
#define SQUARE(x) x*x
-SQUARE(5,5)
// becomes -5 * 5
2. If the macro arguments are expreessions, you should parenthesise them too.
This prevents a different type of problems:
#define SQUARE(x) x*x
SQUARE(5+2)
// becomes 5 + 2*5 + 2
Hence the correct way is to write it like this:
#define square(n) ((n)*(n))
-SQUARE(5+2)
// becomes -((5+2)*(5+2))
Using macros as functions is discouraged though (guess why), so use a function instead. For instance:
inline double square(n) { return n*n; }
The Expansion of macro will be like:
j = 16/SQUARE(2);
j = 16/2*2;
Which is equal to : j = (16/2)*2; Means j = 16;
and :
j = 16/(SQUARE(2));
j = 16/(2*2);
Which is equal to : j = 16/4; Means j = 4;
Because the macro will be expanded as:
j = 16/2*2;
The pre-compiler does not do any processing on the expansion. It places the expanded macro in your code as it is. Since you have not parenthesized the replacement text it wont do it for you in the main code as well. Make it :
#define SQUARE(n) ((n)*(n))
The first example is evaluated as:
16 / 2 * 2
(16 / 2) * 2
8 * 2
16
The second example is evaluated as:
16 / (2 * 2)
16 / 4
4
Add parenthesis to you preprocessor statement to control the order of operations:
#define SQUARE(n) ((n)*(n))
The outer parenthesis in ((n)*(n)) ensure that n is squared before any outside operation is performed. The inner parenthesis (n) ensure that n is correctly evaluated in cases where you pass an expression to SQUARE like so:
16 / SQUARE(2 * 2)
16 / ((2 * 2)*(2 * 2))
16 / (4 * 4)
16 / 16
1
you'll get
j =16/2*2; // (16 / 2) * 2 = 16
Its because Whenever macro name is used, it is replaced by the contents of the macro.its simple rule of working of macro.
Case 1 : result 16
define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
its get expand as below
j =16/SQUARE(2);
so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n
j = 16/2*2
j = (16/2)*2
j = 8*2
j =16
Case 2 : result 4
define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}
its get expand as below
j =16/(SQUARE(2));
so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n
j = 16/(2*2)
j = 16/(4)
j = 4
Hope this will help