This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 2 years ago.
I want to define several macros to calculate the size of a type. The following is an example running normally.
#include <stdio.h>
#define A sizeof(long long) / sizeof(int)
#define B 36 / A
int main(){
printf("%zu %zu\n", A, B); // print out: 2 1
}
While it becomes strange when using SIMD vectors, for example (the definition of A)
#include <x86intrin.h>
#include <stdio.h>
#define A sizeof(__m128i) / sizeof(int)
#define B 36 / A
int main(){
printf("%zu %zu\n", A, B); // print out 4 0
}
What's the issue?
Remember that macros are not variables: they're merely substituted tokens. So B expands to
36 / sizeof(__m128i) / sizeof(int)
Division in C and C++ associates left-to-right so this is equivalent to
(36 / sizeof(__m128i)) / sizeof(int)
If sizeof(__m128i) is 16 and sizeof(int) is 4, then this expression is (36 / 16) / 4. Now integer division in C and C++ truncates, so 36/16 is 2, and 2/4 is 0.
For this reason, you should always parenthesize macros that expand to expressions:
#define A (sizeof(__m128i) / sizeof(int))
#define B (36 / A)
If using C++, a better solution is not to use macros at all; constants in C++ are quite fully featured, and avoid this issue.
constexpr std::size_t A = sizeof(__m128i) / sizeof(int);
constexpr std::size_t B = 36 / A;
With
#define A sizeof(__m128i) / sizeof(int)
#define B 36 / A
then the macro B will expand as 36 / sizeof(__m128i) / sizeof(int) which is evaluated as (36 / sizeof(__m128i)) / sizeof(int).
The result of the first division will be zero, and zero divided with anything is zero. Which is the result you get.
The solution, as almost always when having trouble with macros, is to add explicit parentheses in your macro definitions:
#define A (sizeof(__m128i) / sizeof(int))
#define B (36 / A)
Related
What is the difference of the 2 following statements, regarding the use of parenthesis? (No pointers or so)
#define UART1_BAUD (460800)
#define UART2_BAUD 9600
There is no difference when the macros are used normally as operands in expressions.
Note however, there is a difference in
#define A 4 + 7
#define B (5 + 3)
if you use the macros as
int a = 6 * A; // 6 * 4 + 7 ==> 24 + 7
int b = 6 * B; // 6 * (5 + 3) ==> 6 * 8
As a rule of thumb: use, and abuse, parenthesis in macros.
When parenthesis immediately follow the macro name, it's a function-like macro
#define SQUARE(BAR) ((BAR) * (BAR)) // use and abuse parenthesis
#define sqr(a) a*a
int main()
{
int i;
i = 64 / sqr(4); //answer of this expression is 64.
printf("%d", i);
return 0;
}
In this code the output is 64, and according to the rules, the expression i = 64 / sqr(4) should be solved as i = 64 / 4*4, which gives a result of 4, but the output of the program is 64. Why?
Macros are not evaluated like functions, they are expanded in place. The statement
i = 64 / sqr(4);
expands to
i = 64 / 4*4;
Both of the multiplication and division operators have the same precedence and are left-associative, so the above statement is parsed as
i = (64 / 4) * 4;
Thus, you are multiplying the result of 64 / 4 by 4, rather than dividing 64 by the result of 4 * 4.
They way to avoid precedence and associativity issues with macros like this is to enclose the expansion in parentheses:
#define sqr(a) (a * a)
By itself, though, that’s not sufficient - if you do something like sqr(1+2), that will expand to (1+2*1+2), which evaluates to 5 instead of the expected 9. You also need to parenthesize the argument(s) as well as the overall expression:
#define sqr(a) ((a) * (a))
Now your statement expands to
i = 64 / ((4) * (4));
and will evaluate to what you expect.
I'll try to keep this answer simple:
Macros is a set of code that just get replaced at the time of compilation.
Now, if you replace sqr(4) with 4*4
It becomes something like: 64/4*4.
Now, if you apply basic rule of BODMAS. It gets executed as follows:
64/4= 1616*4= 64 i.e first division with 4 then multiplication with 4 that gives 64
You need to look at the order of operations. Multiplication is done first, so it meant (64 * 4) / 4. Here's an updated version with parenshases around your macro:
#define sqr(a) ((a)*(a))
int main()
{
int i;
i = 64 / sqr(4); //answer of this expression is 4.
printf("%d", i);
return 0;
}
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.
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.
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.