32

How do I implement no-op macro in C++?

#include <iostream>   

#ifdef NOOP       
    #define conditional_noop(x) what goes here?   
#else       
    #define conditional_noop(x) std::cout << (x)   
#endif   
int main() {       
    conditional_noop(123);   
}

I want this to do nothing when NOOP is defined and print "123", when NOOP is not defined.

lillq
  • 14,758
  • 20
  • 53
  • 58
Anton Daneyko
  • 6,528
  • 5
  • 31
  • 59
  • 3
    If your using msvc, the `__noop` intrinsic should be of interest to you, and unlike a few of the presented solutions, you won't get something like an accidental dangling else – Necrolis Mar 26 '11 at 07:35

9 Answers9

58

While leaving it blank is the obvious option, I'd go with

#define conditional_noop(x) do {} while(0)

This trick is obviously no-op, but forces you to write a semicolon after conditional_noop(123).

avakar
  • 32,009
  • 9
  • 68
  • 103
  • 2
    Helpful answer for me! In my case, I needed to no-op some kernel level printfs). For anyone else looking here, to do a variable argument noop macro, one can do `#define conditional_noop(x,...) do {} while(0)` – Michael Dautermann Jan 30 '12 at 11:37
  • This will leave a compiler warning that expression is constant though. – Mo0gles Jul 07 '15 at 10:25
  • @Mo0gles, on msvc it will, though I'm surprised you're the first one to complain :) We have this warning disabled for this reason. – avakar Jul 07 '15 at 13:36
31

As mentioned before - nothing.
Also, there is a misprint in your code.
it should be #else not #elif. if it is #elif it is to be followed by the new condition

#include <iostream>   

#ifdef NOOP       
    #define conditional_noop(x) do {} while(0)
#else       
    #define conditional_noop(x) std::cout << (x)   
#endif  

Have fun coding! EDIT: added the [do] construct for robustness as suggested in another answer.

Andrew
  • 2,309
  • 4
  • 27
  • 42
  • 9
    the above is incorrect. if you have conditional_noop within a control block not surrounded by braces. See avakar's solution for the robust way that'll always work. – Vitali Jul 14 '11 at 04:50
22

Defining the macro to be void conveys your intent well.

#ifdef NOOP
    #define conditional_noop(x) (void)0
#else
Andrew Keeton
  • 22,195
  • 6
  • 45
  • 72
14
 #ifdef NOOP       
     #define conditional_noop(x)   
 #elif  

nothing!

Toad
  • 15,593
  • 16
  • 82
  • 128
6
#ifdef NOOP
    static inline void conditional_noop(int x) { }
#else 
    static inline void conditional_noop(int x) { std::cout << x; }
#endif

Using inline function void enables type checking, even when NOOP isn't defined. So when NOOP isn't defined, you still won't be able to pass a struct to that function, or an undefined variable. This will eventually prevent you from getting compiler errors when you turn the NOOP flag on.

BMDan
  • 282
  • 5
  • 12
Nicolas Viennot
  • 3,921
  • 1
  • 21
  • 22
  • 1
    +1 for the only (so far, anyway) solution not using a macro. But what is the `static` for? And wouldn't it be better to make this a template so that it doesn't just accept `int`? – sbi Aug 20 '09 at 18:34
  • 1
    The static removes linker errors if the definition exists in a header file that is included in multiple .cpp files. Changing it to a templated function would work just fine, but that would remove the type checking (especially when NOOP is defined, since nothing is done with x). – moswald Aug 20 '09 at 21:15
4

You can just leave it blank. You don't need to follow the #define with anything.

Justin
  • 9,419
  • 7
  • 34
  • 41
4

Like others have said, leave it blank.

A trick you should use is to add (void)0 to the macro, forcing users to add a semicolon after it:

#ifdef NOOP       
    #define conditional_noop(x) (void)0
#else       
    #define conditional_noop(x) std::cout << (x); (void)0
#endif  

In C++, (void)0 does nothing. This article explains other not-as-good options, as well as the rationale behind them.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • 5
    By having two statements in the second macro, you may have also just forced users to use braces when they wouldn't otherwise be required, and forgetting the braces may or may not have an effect on the program. The FAQ you linked to explains how to avoid that problem. – Rob Kennedy Aug 20 '09 at 17:30
1

As this is a macro, you should also consider a case like

if (other_cond)
    conditional_noop(123);

to be on the safe side, you can give an empty statement like

#define conditional_noop(X) {}

for older C sometimes you need to define the empty statment this way (should also get optimized away):

#define conditional_noop(X) do {} while(0)
  • 6
    The `do-while` trick has nothing to do with the age of the compiler. – avakar Aug 20 '09 at 14:47
  • 4
    You misunderstood the reason behind using `do { } while (0)` and consequently your first code isn’t sufficient and wouldn't work. To see why, imagine your above example code had an `else` branch … – Konrad Rudolph Aug 20 '09 at 14:50
0

I think that a combination of the previous variants is a good solution:

#ifdef NOOP
    static inline void conditional_noop(int x) do {} while(0)
#else 
    static inline void conditional_noop(int x) do { std::cout << x; } while(0)
#endif

The good thing is that these two codes differ only inside a block, which means that their behaviour for the outside is completely identical for the parser.

yo'
  • 811
  • 11
  • 22