48

If I define a function macro with no actual body, is it like an empty string with the compiler (i.e. It doesn't generate any extra instructions at compile time)?

Example:

#define SomeMacro(a)

SomeMacro("hello"); // This line doesn't add any instructions, does it?
Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145

4 Answers4

62

You're absolutely correct, the empty macro doesn't generate any code.

I've seen two places where this is useful. The first is to eliminate warnings when a function parameter isn't used:

#define UNUSED(x)

int foo(int UNUSED(value))
{
    return 42;
}

The second is when you use conditionals to determine if there should be code or not.

#ifdef LOGGING_ENABLED
#define LOG(x) log_message(x)
#else
#define LOG(x)
#endif
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Hi I do n't understand your first code [Here I tried](http://codepad.org/WbSlIXkc) .. I think its just an error to write `int foo(int UNUSED(value))` if macro definition is balank **?** – Grijesh Chauhan Mar 08 '13 at 23:09
  • 3
    @GrijeshChauhan, you've just discovered one of the differences between C and C++. See here: http://codepad.org/flX8m3sk – Mark Ransom Mar 08 '13 at 23:16
  • Thanks Got it :) nice working.. actually I [asked a question](http://stackoverflow.com/questions/15256090/macro-without-definition-in-c) a day back. – Grijesh Chauhan Mar 08 '13 at 23:20
  • In addition to I got answer and your answer I got one more usefulness of macro without body [here THROW_](http://stackoverflow.com/questions/2486386/why-do-i-see-throw-in-a-c-library?answertab=votes#tab-top) .. – Grijesh Chauhan Mar 08 '13 at 23:26
  • anyway for unused parameter warning, you just need to cast it to void so in function body: (void) value; – CoffeDeveloper Sep 15 '14 at 13:20
  • 1
    @DarioOO I've seen that done as a macro too, just to document why you're doing such a strange thing. – Mark Ransom Sep 15 '14 at 14:33
  • In the former case, `(void)value;` works just as well whilst being language-level (and thus doesn't have the negative aspects of macros). The second case is somewhat more reasonable. – Pharap May 05 '18 at 23:46
  • @Pharap I make no judgement on whether it's a good idea, I'm just reporting what I've seen. – Mark Ransom May 06 '18 at 03:05
31

Your code is not totally correct, I suggest you to put empty braces in your macro

#define somemacro(a) {}

the reason is simple, you code will be much more safe!

take this example:

if(Value)
    somemacro(a)
else
    somemacro(b)

If the macro is empty, your code will not compile! (Expected primary-expressione before "else"). Anyway certain style rules force you to write

if(Value)
{
    somemacro(a)
}
else
{
    somemacro(a)
}

so that will not be a problem.

Another option is to use ";" instead of "{}" but that option in the same case will give you compile time warnings, while empty braces will not give warnings nor errors! (semicolon is still better even if give warnings) ;)

take following case

if(value)
    somemacro(a);
else
    somemacro(b);

will expand to

if(value)
{};
else
{};

that can't compile!

That's why macros are evil

(since macros are simple text-replacement, the rule of dumbs should be to always try to manually replace the code and see what happens, there are also tools that will replace macros for you showing the expanded code.)

Still guessin if there is a macro that is totally safe? Yes it is called "NOP"

#define somemacro(a) ((void)0)

that will work in any case (even source files of compilers use that as NOP, for example just look at "assert.h"

CoffeDeveloper
  • 7,961
  • 3
  • 35
  • 69
  • 4
    The exact intend was to show a most correct usage of macros. a empty function macro can't still be used in certain cases. So any random user reading you post must be aware that using a "((void)0)" is better choice. And anyway that's a "NOP" but not a NOP. infact no extra assembly is generated for ((void)0) while a NOP instruction is still assembly code. Safety of code should always be considered. Still no reason for thumbs down anyway. – CoffeDeveloper Dec 31 '12 at 14:08
  • 4
    Upvoted because this is the only answer caring about misuse – though probably the emphasis should go directly to the ((void) 0). For the ones saying that this is unnecessary (@Qix), check [the very GCC manual](https://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html#Macro-Pitfalls). – hmijail Jul 22 '15 at 13:13
  • 4
    Um... That's exactly what `do { } while (0)` idiom is for. Using plain `{}` for that purpose is not a good idea since it requires the user to remeber NOT to put a `;` after that macro invocation. – AnT stands with Russia Apr 05 '17 at 00:23
  • 1
    I just showed 3 possible solutions showing why one was slightly better and the other one much more better. `do {} while(0)` is another valid alternative, even though some buggy compilers throw a warning for that. – CoffeDeveloper Apr 06 '17 at 06:46
7

That's correct. Your code expands to

;

after preprocessing.

Note that you can ask your compiler to show you the code after preprocessing (in gcc, this is the -E option; your compiler may vary).

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • The code doesn't generate anything, not even a semi-colon. (verified with gcc 4.5.2) – shinkou Feb 08 '12 at 04:38
  • 6
    @shinkou, the semi-colon is outside the macro so it should be part of the final code. – Mark Ransom Feb 08 '12 at 04:41
  • @shinkou Doesn't generate any Assembly/bytecode? Or doesn't generate any code? Because the preprocessor is a separate step to the compilation and linking. The semicolon in the code in the question doesn't magically disappear _after preprocessing alone_; however, you're correct that in the final compiled executable it's not there. – Nic Mar 29 '18 at 23:44
6

The preprocessor performs literal substitution with all macros.

Therefore, if you define an "empty" macro, then each place that identifier appears in your code will be replaced with an empty statement by the preprocessor before the compiler ever runs.

So yes. No code will be generated for the example given in your question.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574