C preprocessors and order of operations

2020-03-13 04:13发布

问题:

I'm learning C, but I do not understand this:

#define square(x) x*x
a = square(2+3) //a = 11

When this is run, why does a end up being 11?

回答1:

It expands to 2+3*2+3, which is equivalent to 2+(3*2)+3. Use parentheses to fix it:

#define square(x) ((x)*(x))

Now try it with square(x++) and you'll run into more problems (undefined behavior). Avoid doing this as a macro if you can.



回答2:

square(2+3) expands to 2+3*2+3 which is equivalent to 2+(3*2)+3 [* has higher precedence than +]

On gcc you can use -E option to see what your preprocessor generates

C:\Users\SUPER USER>type a.c
#define square(x) x*x

int main()
{
   a = square(2+3); //a = 11
}

C:\Users\SUPER USER>gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"


int main()
{
   a = 2+3*2+3;
}

Remedy

Try this

#define square(x) ((x)*(x))


回答3:

Try:

#define square(x) ((x)*(x))


回答4:

Because 2 + 3 is substituted literally in the expression x * x, it becomes 2 + 3 * 2 + 3, and the * operator has a higher precedence so you don't get the expected result.

Always enclose macro arguments and the whole expression in parentheses to avoid this:

#define SQUARE(x) ((x) * (x))

Also note that any expression you pass will be evaluated twice, and that can be undesired if the expression has a side effect such as an assignment, or a function call. In these cases it is better to use an inline function.



回答5:

think about what you get when the macro is expanded. The c preprocessor will expand this as

a = 2 + 3 * 2 + 3

You need to correctly define your macro. Always enclose the macro variable in parenthesis. This would give you the expected result.

#define square(x) ((x)*(x))

The macro expansion would be this:

a = ((2 + 3) * (2 + 3))