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
Related
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)
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:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 4 years ago.
I am not able to understand this code
#define sqt(x) x*x
int main(){
print("%d",sqt(3+1));
}
Manually I am getting the output of 10. But when write the code and compile it I am getting the answer as 7. Please explain this.
Remember, since you're using a macro, 3 + 1 is not evaluated before sqt is called. x becomes 3 + 1 (not 4), then order of operation causes an unexpected answer to be produced since addition happens after multiplication.
Or in other words:
sqt(3 + 1)
expands to:
3 + 1 * 3 + 1
Then, when you evaluate this like you would any other equation:
3 + 1 * 3 + 1 // Multiplication happens first
= 3 + 3 + 1
= 7
This is a good example of why you shouldn't use macros unless they're strictly necessary, or you've made proper care to ensure that things like order of operation mistakes don't happen. As #Barmar points out this particular case can be remedied by having the macro expand to include explicit parenthesis:
#define sqt(x) ((x)*(x))
Which would cause the evaluation to differ and give a proper answer:
(3 + 1) * (3 + 1)
4 * 4
16
Can someone explain to me why the value of y here is 13?
#include <stdio.h>
#define avg_sum(n) n * (n-1)/2
int main(){
int y;
int z = 9;
y = avg_sum(z+1);
printf("y=%i\n",y);
}
avg_sum(9+1) 9+1 * (9+1-1)/2 = 9 + 9/2 = 9+ 4 = 13
macros expand each time so 9+1 is not the same as 10, it might be better with safeguarding parenthesis as follows:
#define avg_sum(n) ((n) * ((n)-1)/2)
but an equivelant function will do you much better and be more intuitive and will evaluate arguments only once
avg_sum(a++) will be ((a++) * ((a++)-1)/2) and will increment a twice whereas a function will not have these issues since all arguments are evaulated before the function is called
The best way to answer these sorts of questions is to simply expand the macro in question:
y = avg_sum(z+1);
y = z + 1 * (z + 1 - 1) / 2
y = 9 + 1 * (9 + 1 - 1) / 2
y == 13
This is why you add parentheses around your macro arguments.
#define avg_sum(n) ((n) * ((n)-1)/2)
y = avg_sum(z+1);
expands to z + 1 * (z+1-1)/2 but it's wrong. Change your macro to
#define avg_sum(n) ((n) * ((n)-1)/2)
And always parenthesize as well arguments of functional macros as the macro itself . It's an important rule.
I have the simple following C code
#define Sqrt(A) A * A
int main(void) {
int A = 10;
int x = Sqrt(A+1);
return 0;
}
For some reason, when I used it like that, with A+1, I get x to be 21, which is probably 10+11.
My question is, how is the multiplication is being ignored?
If I switch the macro with the macro text, I get the right result which is 121.
Thanks.
First, your Sqrt is misnamed, should be Square (not square root)
Then, generate the preprocessed form (i.e. with gcc -C -E) and look inside it.
#define Sqr(A) A * A
int a = 10;
int x = Sqr(a+1);
where the last line is expanded as
int x = a+1 * a+1;
Which is parsed as
int x = a+(1*a)+1;
Moral of the story, always use extra parenthesis in macro definition, i.e.
#define Sqr(A) ((A)*(A))
Even with such a definition, Sqr(a++) is probably undefined behavior and at least is naughty.
So you want to avoid macros and actually, learn to use inline functions like
inline int square(int a) { return a*a; };
BTW, you will want to make it static inline not just inline (and put that in a header file)
'cos
#define Sqrt(A) A * A
makes
Sqrt(A+1);
translate to
A + 1 * A + 1
and A is 10
so you get
10 + 1 * 10 + 1
Now do the maths!
BTW sqrt has seems to say square root not squared!
You define the macro as A * A. So, Sqrt(A + 1) expands to A + 1 * A + 1, which is, due to operator precedence, equal to 2 * A + 1 - you've got 2 * 10 + 1 = 21.
That's why you should always parenthesize your macros and their arguments:
#define Sqrt(A) ((A) * (A))
By the way, why a macro? What if one day you write Sqrt(A++)? Then you can expect nasal demons. It would be safer to write an inline function instead (horribile dictu, a correctly named inline function):
static inline double square(double x)
{
return x * x;
}
Inside the macro, A is replaced with whatever was passed into the macro invocation. In this case, that is A+1. This means that the macro gets expanded to:
A+1 * A+1
Due to operator precedence, this is interpreted as A + 1*A + 1, or 10 + 10 + 1 = 21.
You should define the macro as #define Sqrt(A) ((A) * (A))
BODMAS rule buddy!! as the previous answers suggests. Multiplication takes place before your addition.
Your opertaion Sqrt(A+1) where A = 10 will evaulate to 10+1*10+1
10+10+1
21!!
Macros are substituted literally and then evaluated.
Since multiplication has more priority than addition, when you give A+1 to the macro it becomes 10 + 1 * 10 + 1 => 10 + 10 + 1 => 21
Likewise if you give A+2 ..... 10 + 2 * 10 + 2 => 10 + 20 + 2 => 32.
when you call x = MACRO_NAME(A+1); this statement is replace as x = A + 1 * A + 1
in c priority of multiplication is more than addition so it will be 1st executed 1*A which give as A, then A+A+1 will give you result as 21`enter code here`
i.e A+1*A+1
= A+A+1
= 21
for proper answer you need to write Macro as #define MACRO_NAME(A) (A) * (A) which give you result as
121