I tried to run this code:
#define ROW_CNT 8;
#define COLUMN_CNT 24;
#define FIRST_COLUMN 2;
unsigned int volume[ROW_CNT][COLUMN_CNT][ROW_CNT];
but I get the following errors:
expected identifier or '(' before ']' token
Why is that?
Take off the semicolons on your #defines.
The #define directives are handled by the preprocessing stage of compilation, which is all about text substitution. So, whenever the preprocessor performs text substitution, your program becomes
unsigned int volume[8;][24;][2;];
which isn't valid C.
#define ROW_CNT 8;
#define COLUMN_CNT 24;
#define FIRST_COLUMN 2;
should be
#define ROW_CNT 8
#define COLUMN_CNT 24
#define FIRST_COLUMN 2
semicolons should not be used for #define
A pre-processor definition, such as ROW_CNT, replaces any instances of the identifier in your code with the value it's defined as being. Therefore once the pre-processor has expanded your macros, your code will look like:
unsigned int volume[8;][24;][2;];
As you can see, the semicolon is included after 8, 24 and 2, since that's how you defined ROW_CNT, COLUMN_COUNT and FIRST_COUNT to be, and that's obviously not valid C syntax.
Remove the semicolons from the end of your #defines and the code will compile.
Related
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.
Why this code gives an error:
#include <stdio.h>
#define Rep (int)6
int main(){
#if Rep==6
printf("T");
#else
printf("F");
#endif
return 0;
}
Why does it refuse the casting?
Is it a 'preprocessor error' or a 'compiler error'?
This is a preprocessor error. It happens because the preprocessor does not understand how to cast a variable. You cannot use any C code with #if, just simple numbers, or macros which expand to a number.
If you cannot modify Rep, you can work around this with a helper macro, which removes the casting from the beginning:
#include <stdio.h>
#define X(x)
#define Y(x) X x
#define Rep (int)6
int main(void) {
#if Y(Rep) == 6
printf("%d\n", Y(Rep)); // prints 6
#endif
return 0;
}
Preprossor macros that combine casts and that still should work in #if are easy to write: you just add a little + before the number. In your case
#define Rep ((int)+6)
The preprocessor replaces identifiers that it doesn't know by 0 so the end result is the same value.
But also, the cast in your Rep macro by itself is quite useless. 6 is an int, anyhow. So better avoid a cast for all integer types that have their own literals, combinations of U and L as suffix should do in most cases.
#define VAL1CHK 20
#define NUM 1
#define JOIN(A,B,C) A##B##C
int x = JOIN(VAL,NUM,CHK);
With above code my expectation was
int x = 20;
But i get compilation error as macro expands to
int x = VALNUMCHK; // Which is undefined
How to make it so that NUM is replaced first and the JOIN is used?
You can redirect the JOIN operation to another macro, which then does the actual pasting, in order to enforce expansion of its arguments:
#define VAL1CHK 20
#define NUM 1
#define JOIN1(A, B, C) A##B##C
#define JOIN(A, B, C) JOIN1(A, B, C)
int x = JOIN(VAL,NUM,CHK);
This technique is often used with the pasting and stringification operators in macros.
So I was wondering when is to use
#define xxx (yyy)
vs
#define xxx yyy
My project includes a files that has its own defines such at AD0_ADMD_CT if I wanted to redefine them would I need to use (AD0_ADMD_CT) or just AD0_ADMD_CT in the define or not?
AD0_ADMD_CT is a defined as
#define AD1_ADMD_CT (IO_AD1.ADMD.bit.CT)
So it would be either
#define AD0_COMPARETIME (AD0_ADMD_CT)
or
#define AD0_COMPARETIME AD0_ADMD_CT
There is no difference in both. In first case XXX is replaced by yyy and by (yyy) is second case. The convention to use brackts is to avoid logical errors that may occur. For example you define addition function as:
#define f(N) N+N
int a = f(5)*f(5)
Expected value is 10*10 = 100 , but output is 35 because at compile time is becomes
int a = 5+5*5+5, so using operator preference rule, output changes.
So parenthesis avoid these type of errors.
By adding parentheses, you are forcing the argument inside the parentheses to be evaluated before the rest of the macro body, so if you had
#define MULT(x, y) (x) * (y)
// now MULT(3 + 2, 4 + 2) will expand to (3 + 2) * (4 + 2)
It does not appear to affect your current case unless there is more to your macros.
It's very important if you have operators in your macro. For example:
#define ADD(x,y) x + y
ADD(1,2) * 3 /* Should be 9, is 7 */
Should be:
#define ADD(x,y) (x + y)
ADD(1,2) * 3 /* 7 */
These precedence problems also apply for the arguments, as #Gi Joe says, and need to be wrapped in parens for precedence.
However, for a macro like:
#define MAGICNUM 3
It doesn't matter.
An important thing to remember is that the preprocessor simply expands macros. For example, if you had the following lines:
#define AD0_COMPARETIME_1 (AD0_ADMD_CT)
#define AD0_COMPARETIME_2 AD0_ADMD_CT
num_1 = AD0_COMPARETIME_1;
num_2 = AD0_COMPARETIME_2;
After the first expansion you'd have this:
num_1 = (AD0_ADMD_CT);
num_2 = AD0_ADMD_CT;
And after the second expansion you'd have this:
num_1 = ((IO_AD1.ADMD.bit.CT));
num_2 = (IO_AD1.ADMD.bit.CT);
A problem may arise, as stated in other answers, when an expression is expanded.
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.