1

why using do{}while(0) in macro expansion

#define FN(x) do{ f1(x); f2(x);} while(0)

Below code will do the same right?

#define FN(x) { f1(x); f2(x); }

if(condition)
FN(val)  // **without a semicolon**
else
f3();

which simply expands like below.

if(condition)
{ f1(val); f2(val); }
else
f3();

There is no issue seems in macro use FN(val) without a semicolon in GCC.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • 3
    They are not the same. The first version needs a semicolon somewhere. – Weather Vane Jul 06 '23 at 14:32
  • 6
    Not having a semicolon after what looks like a function call is confusing and looks wrong. – Shawn Jul 06 '23 at 14:32
  • Sorry for the confusion, I am just checking what is the advantage of #define FN(x) do{ f1(x); f2(x);} while(0) over #define FN(x) { f1(x); f2(x); } – user2999236 Jul 06 '23 at 14:37
  • 1
  • For the first version you don't need to know whether `FN()` is a function or a function like macro. Just use `FN();` and you are done. For the second you must know what exactly `FN()` is because you must add a `;` or you must omit. Thus, first one is easier to handle. – Gerhardh Jul 06 '23 at 14:40
  • There is no issue seems in macro usage like above- FN(val) without a semicolon in GCC. – user2999236 Jul 06 '23 at 14:40
  • 1
    @user2999236: The duplicate has you covered there. The latter does weird and terrible things in specific contexts where the dangling semi-colon can lead to erroneous results; you want to *require* the semi-colon and *use* the semi-colon, consistently, or you hit corner cases filled with corner cases. Practically though, just use a function; you referred to `x` twice, now `FN(++i)` does unexpected and terrible things that it wouldn't do if it were a function. – ShadowRanger Jul 06 '23 at 14:41
  • @user2999236: Yeah, it allows it. But that code looks *wrong* (if you change it to a function later, it will break; in certain contexts, it will change behavior based on the presence or absence of a semi-colon). Why do you consider "I can write code full of code smell" to be a selling point? – ShadowRanger Jul 06 '23 at 14:43
  • @user2999236 "*There is no issue...*" - in *this particular example*, yes. But macros can be used in other ways where your proposed code would produce invalid/incorrect results. Did you read the answers in the [linked duplicate](https://stackoverflow.com/questions/154136/) yet? – Remy Lebeau Jul 06 '23 at 14:43
  • @ShadowRanger The linked question is about C++, so not a duplicate. – 12431234123412341234123 Jul 06 '23 at 15:44
  • @12431234123412341234123: Both questions are about the C preprocessor and apply equally to C and C++. Nitpicking for the sake of nitpicking is pointless, and you're not even nitpicking properly, since the dupe isn't even specifically C++-targeted. This question is nearly identical to the other, and both lead to the same answers; it's a duplicate. – ShadowRanger Jul 06 '23 at 16:03
  • Thank you all for your responses.Below are some observations. 1. I just want to ensure which is the best code snippet for embedded applications. 2. Checked whether 'do-while' will produce more assembly lines than 'if' statement. 3. Seems like both code expands to same assembly code with GCC. so both will take the same instruction cycle. Compiled for both methods. cc -S sample.c => producing same assembly file 'sample.s' – user2999236 Jul 07 '23 at 06:55
  • A more complete answer can be found here: [What is do { } while(0) in macros and should we use it?](https://software.codidact.com/posts/279576) – Lundin Jul 07 '23 at 12:50

0 Answers0