Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C macros and use of arguments in parentheses

Example

#define Echo(a)  a
#define Echo(a) (a)

I realize there probably isn’t a significant difference here, but why would you ever want to include the a within parenthesis inside the macro body? How does it alter it?

like image 243
rubixibuc Avatar asked Aug 25 '11 07:08

rubixibuc


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.

Can we pass arguments in macro?

Function-like macros can take arguments, just like true functions. To define a macro that uses arguments, you insert parameters between the pair of parentheses in the macro definition that make the macro function-like. The parameters must be valid C identifiers, separated by commas and optionally whitespace.

How many arguments macro can have in C?

For portability, you should not have more than 31 parameters for a macro. The parameter list may end with an ellipsis (...).

Which is a valid type of arguments in macro?

There are two types of arguments: keyword and positional. Keyword arguments are assigned names in the macro definition; in the macro call, they are identified by name.


2 Answers

Suppose you have

#define mul(x, y)  x * y

What happens if I say:

mul(a + 5, 6); /* a + 5 * 6 */

Now if I slighlty change the macro:

#define mul(x, y)  ((x) * (y))
mul(a + 5, 6); /* ((a + 5) * (6)) */

Remember, the arguments aren't evaluated or anything, only textual substitution is performed.

EDIT

For an explanation about having the entire macro in parentheses, see the link posted by Nate C-K.

like image 178
cnicutar Avatar answered Sep 28 '22 20:09

cnicutar


Just for the record, I landed from Here How to fix mathematical errors while using macros and I will try to expand this Answer here to fit the Other one.

You are asking about the difference about:

#define Echo( a )  a
#define Echo( a ) ( a )

which is fine as long as you do not understand the macro it self (I am not an expert too :) ).

First of all you already (probably) know that there is Operator Precedence, so there is a huge difference of this two programs:

1):

#include <stdio.h>
#define ADD( a , b ) a + b

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD (  2 + a ,  2 + b );
    printf( "%d", c );
    return 0;
}

Output:

19

and:

#include <stdio.h>
#define ADD( a , b ) ( a ) + ( b )

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( a , b );
    printf( "%d", c );
    return 0;
}

Output:

15

Now lets preplace + with *:

#define ADD( a, b ) a * b

The compiler treats a * b like for example a == 5 and b == 10 which does 5 * 10.

But, when you say: ADD ( 2 + a * 5 + b ) Like here:

#include <stdio.h>
#define ADD( a , b ) ( a ) * ( b )

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( 2 + a , 5 + b );
    printf( "%d", c );
    return 0;
}

You get 105, because the operator precedence is involved and treats

2 + b * 5 + a

as

( 2 + 5 ) * ( 5 + 10 )

which is

( 7 ) * ( 15 ) == 105

But when you do:

#include <stdio.h>
#define ADD( a, b ) a * b

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( 2 + a , 5 + b );
    printf( "%d", c );
    return 0;
}

you get 37 because of

 2 + 5 * 5 + 10

which means:

2 + ( 5 * 5 ) + 10

which means:

2 + 25 + 10

Short answer, there is a big difference between:

#define ADD( a , b ) a * b

and

#define ADD( a , b ) ( a ) * ( a )
like image 38
Michi Avatar answered Sep 28 '22 19:09

Michi