24

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?

Palec
  • 12,743
  • 8
  • 69
  • 138
rubixibuc
  • 7,111
  • 18
  • 59
  • 98
  • possible duplicate of [The need for parentheses in macros in C](http://stackoverflow.com/questions/10820340/the-need-for-parentheses-in-macros-in-c) – Palec Apr 29 '15 at 08:35
  • The question [The need for parentheses in macros in C](http://stackoverflow.com/questions/10820340/the-need-for-parentheses-in-macros-in-c) is a duplicate of this, rather than vice versa, and is now closed as such. – Jonathan Leffler Feb 10 '18 at 20:58
  • Related questions: [Can we remove the parentheses around arguments in C macro definitions?](https://stackoverflow.com/questions/27752386/can-we-remove-parentheses-around-arguments-in-c-macros-definitions) and [When can the parentheses around arguments in macros be omitted?](https://stackoverflow.com/questions/20964369/when-can-the-parentheses-around-arguments-in-macros-be-omitted) – Jonathan Leffler Feb 10 '18 at 21:01

2 Answers2

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.

Community
  • 1
  • 1
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 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? – rubixibuc Aug 25 '11 at 07:30
  • You probably mean `foo(bar) (bar)->something`, and yes, they are necessary. – cnicutar Aug 25 '11 at 07:31
  • Sry to ask, but how is it nessecary there? – rubixibuc Aug 25 '11 at 07:33
  • I read the entire linked page and still dont't see how that could get parsed wrong – rubixibuc Aug 25 '11 at 07:34
  • 2
    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` – nos Aug 25 '11 at 07:41
  • It's ok I think I figured it out – rubixibuc Aug 25 '11 at 07:41
  • Another note worth mentioning is if you have multiple statements in the macro body, it is good practice to put them within a 'do{ ... macro statements... }while(0)'. Otherwise you may trip when using the macro, for instance in a if body, followed by an else (without enclosing braces). – Kaos Aug 25 '11 at 07:42
  • @rubixibuc: the rule is that you fully parenthesize macros and macro parameters unless you *know* it isn't necessary (not 'think' it isn't necessary). There are times when parens will actually mess up macro (for some macros or macro parameters that aren't meant to be expressions), but in general parenthesize everything! – Michael Burr Aug 25 '11 at 08:04
  • The link by Nate C-K is dead. Luckily archive.org wayback machine still has it: https://web.archive.org/web/20151004214455/https://docs.freebsd.org/info/cpp/cpp.info.Macro_Parentheses.html – josch Dec 21 '22 at 10:57
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 )
Michi
  • 5,175
  • 7
  • 33
  • 58
  • Why do you write `auto` before variables? It is totally redundant – Erik W Feb 10 '18 at 17:32
  • @ErikW Please explain me what exactly are you finding wrong with using `auto` in this examples? – Michi Feb 10 '18 at 17:43
  • You never need to write `auto` in C since all variables are auto when declared in scope (except when declared as explicit `static`). It is not wrong, but unnecessary. – Erik W Feb 10 '18 at 21:18
  • @ErikW I can not answer to your question as long as you do not consider that using of auto in C is wrong. – Michi Feb 10 '18 at 22:04
  • Probably would be the same question: why people do not use return in main? Just because is implicit since 99? – Michi Feb 10 '18 at 22:17
  • 1
    @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. – zwol Jan 09 '20 at 14:57
  • 1
    @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. – zwol Jan 09 '20 at 14:59
  • @zwol I do agree that I overreacted with the auto keyword, but even if some one consider it bad styling it does not mean that is wrong. SO is not a code learning system, so there is no misunderstanding here. About the main return I must to disagree with you because here has nothing with code styling when comes to the Standard it self. You can not say “bad styling” if the C standard say you do not need it because it is implicit. Doing that means that you ignore the Standard or you do not accept it. In both cases is wrong. – Michi Jan 10 '20 at 21:40
  • *You can not say “bad styling” if the C standard say you do not need it because it is implicit* -- Yes I can. The C standard says what must be acceptable to a C compiler; it doesn't say anything about what will make code easy for humans to read. – zwol Jan 11 '20 at 15:16
  • I don't know what you mean by "SO is not a code learning system" but it is very important to use good style for the relevant language when answering SO questions, both because it avoids distracting people from the answer, and because people will take your answers as a source of copy-and-paste code years later. – zwol Jan 11 '20 at 15:26