25

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?

3

2 Answers 2

28

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.

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you, I was just confused because in the book I am using, the way they used them seemed redundant. They had something like this foo(bar) (bar)->something, would they be nessecary here?
You probably mean foo(bar) (bar)->something, and yes, they are necessary.
Sry to ask, but how is it nessecary there?
I read the entire linked page and still dont't see how that could get parsed wrong
Suppose you have an array of structs, and you, for some reason do foo(bar+5). That would be perfectly fine if foo were a function, but if it's a macro without the parenthesis, it'll end up as bar+5->something. Similar if bar is a pointer to a pointer, and you do foo(*bar) which ends up as *bar->something , which is certainly wrong, you'll want (*bar)->something
|
0

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 )

11 Comments

Why do you write auto before variables? It is totally redundant
@ErikW Please explain me what exactly are you finding wrong with using auto in this examples?
@Michi These are fundamentally matters of style. Your code is correct in the sense that the compiler will not do anything you didn't want it to do because you put auto on all the variables, but it is bad style because the preferred style in C is not to write auto ever. Similarly, omitting return 0; at the end of main is correct, but bad style; preferred style is not to leave that out. Going against the preferred style makes it harder for other people to read your code, and that in itself is enough reason not to do it.
@Michi These particular style rules do have objective rationales: auto means something completely different (and actually useful) in C++, so writing it in C code may mislead people into thinking that it's meant to be compiled as C++; omitting return 0; in main was UB prior to C99 and is also a weird special case, not consistent with the rest of the language. But not all style rules have objective rationales, and you should adhere to them anyway. Because readability.
Note that in C23, auto takes on a life of its own, rather like it already has done in C++. I firmly agree with the sentiment that C code written at any time in the last 40 years should not use the keyword auto. I'm going to be cautious about using auto even in code intended for C23 — the possibilities for misunderstanding are too large for my comfort (plus I'm struggling to get our code base to use C11 at work; we have at least moved to C99 now).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.