Why is the output 16? (C pogramming) [duplicate] - c

This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 2 years ago.
#include<stdio.h>
#define sqr(x) x*x
int main()
{
int a = 16/sqr(4);
printf("%d", a);
}
if I am not wrong the output should be 1
as ,a = 16/sqr(4) gives 16/16 => 1
but the output is 16
this is happening only when I take division operator(/) ,I am getting correct output when using other operators
may I know the reason? .. and thank you

16 / 4 * 4 is (16 / 4) * 4 = 16
Moral: always take care with macros. In your case you should enclose in parenthesis:
#define sqr(x) ((x)*(x))
There are still problems with this macro as it evaluates the argument twice.
For instance:
int read_int();
int a = 16 / sqr(read_int());
Will unexpectedly evaluate read_int() twice as it expands to:
int a = 16 / ((read_int() * (read_int());
The advice would be to use functions for this. Make it inline to give the compiler better chances to optimize it.

a = 16/sqr(4);
Expanded the above expression gives:
a = 16 / 4 * 4
Which is 16 based on normal mathematical order of operations.
That's why macros should always be enclosed in parentheses:
#define sqr(x) ((x) * (x))

Are you trying to make a function definiton? If yes, then i don't think it should be on a #define. Instead, make a function sqr(x). Here's how:
#include <stdio.h>
int sqr(int x)
{
return x*x;
}
int main()
{
int a = 16/sqr(4);
printf("%d", a);
}
And you'll get the result 1.
Edit: but anyway, you've already get the solution with macros. This is just another way to do what you want.

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.

Is there any difference between this two macros? [duplicate]

This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 3 years ago.
I find no difference between these two macros except the parentheses surrounding the macro in the first one.
Is it a matter of readability or is it a way to deal with the priority of operators?
#define TAM_ARRAY(a) (sizeof(a)/sizeof(*a))
#define TAM_ARRAY2(a) sizeof(a)/sizeof(*a)
Yes, there is a difference. The parentheses are needed so that the result of the macro is evaluated as a single expression, rather than being mixed with the surrounding context where the macro is used.
The output of this program:
#include <stdio.h>
#define TAM_ARRAY(a) (sizeof(a)/sizeof(*a))
#define TAM_ARRAY2(a) sizeof(a)/sizeof(*a)
int main(void)
{
int x[4];
printf("%zu\n", 13 % TAM_ARRAY (x));
printf("%zu\n", 13 % TAM_ARRAY2(x));
}
is, in a C implementation where int is four bytes:
1
3
because:
13 % TAM_ARRAY (x) is replaced by 13 % (sizeof(x)/sizeof(*x)), which groups to 13 % (sizeof(x) / sizeof(*x)), which evaluates to 13 % (16 / 4), then 13 % 4, then 1.
13 % TAM_ARRAY2(x) is replaced by 13 % sizeof(x)/sizeof(*x), which groups to (13 % sizeof(x)) / sizeof(*x), which evaluates to (13 % 16) / 4, then 13 / 4, then 3.
Along these lines, TAM_ARRAY would be better to include parentheses around the second instance of a as well:
#define TAM_ARRAY(a) (sizeof(a)/sizeof(*(a)))
Macros are replaced textually in an early phase of code translation. Unless side effects are specifically expected, it is very important to fully parenthesize macro arguments in the macro expansion and the macro expansion itself if it is an expression.
In the case posted, you are unlikely to have a problem because few operators have higher precedence and they would probably not be used around the macro expansion, but here is a pathological example:
TAM_ARRAY(a)["abcd"] expands to (sizeof(a)/sizeof(*a))["abcd"] whereas
TAM_ARRAY2(a)["abcd"] expands to sizeof(a)/sizeof(*a)["abcd"] which is equivalent to sizeof(a) / (sizeof(*a)["abcd"]).
Note however that an operator with the same precedence placed before the macro expansion such as % would definitely cause problems as explained in Eric Postpischil's answer.
Note also that a should be parenthesized too:
#define TAM_ARRAY(a) (sizeof(a) / sizeof(*(a)))
The way macros work is that the code is "swapped out" when compiling.
So something like
#define ADD(i, j) i + j
int k = ADD(1, 2) * 3
would be seen as: int k = 1 + (2 * 3)
Whereas,
#define ADD(i, j) (i + j)
int k = ADD(1, 2) * 3
would be seen as: int k = (1 + 2) * 3
So, there are two macros likely because of operator priority.

Why doesn't this math work with macros? [duplicate]

This question already has answers here:
some error in output in using macro in C
(3 answers)
Closed 9 years ago.
Why doesn't this math work with macros in C?
#include <stdio.h>
#define FOO 6
#define BAR 32
#define MULT FOO * BAR
main() {
int x = 28296;
int y = x / MULT;
printf("%d / %d = %d\n", x, MULT, y);
return 0;
}
The result of this is:
28296 / 192 = 150912
Why isn't it 147? If I set a variable " int mult" equal to MULT, and use the variable in the expression (int y = x / mult) it works as expected.
#define tells the preprocessor to replace the code before compilation, so your line actually says:
int y = x / 6 * 32;
since * and / operators have the same precedence, and are evaluated from left to right, you get (x/6) * 32. The compiler would probably do this calculation for you since x is known to it.
Instead, use parenthesis when defining macros like this
Put a bracket around the macro:
#define MULT (FOO * BAR)
Now, you'll get 147.
The reason getting 150912 is that after macro expansion the expression is equivalent to:
y = 28296 / 6 * 32;
and hence it's evaluated as 28296/6 and then multiplied by32.
As #kevin points out, it's better to put brackets around FOO and BAR as well in general case to avoid surprises like this.

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