Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The need for parentheses in macros in C [duplicate]

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.

like image 715
Kushal Avatar asked May 30 '12 16:05

Kushal


People also ask

Why do we recommend the use of parentheses for formal arguments used in a macro definition?

The macro and its parameters should be enclosed in parentheses. When macro parameters or expression are not parenthesized, the intended logic may get disrupted after expanding the macro.

What is the need for macro in C?

In C, the macro is used to define any constant value or any variable with its value in the entire program that will be replaced by this macro name, where macro contains the set of code that will be called when the macro name is used in the program.

What does ## mean in C macro?

The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.

What is macro replacement in C?

Macro substitution is a mechanism that provides a string substitution. It can be achieved through "#deifne". It is used to replace the first part with the second part of the macro definition, before the execution of the program. The first object may be a function type or an object.


3 Answers

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.

like image 198
Babak Naffas Avatar answered Oct 08 '22 02:10

Babak Naffas


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.

like image 44
pb2q Avatar answered Oct 08 '22 02:10

pb2q


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.

like image 42
Luchian Grigore Avatar answered Oct 08 '22 00:10

Luchian Grigore