views:

702

answers:

8

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.

+3  A: 

Defining the macro to be void conveys your intent well.

#ifdef NOOP
    #define conditional_noop(x) (void)0
#else
Andrew Keeton
You should have `(void)0` since `(void);` is a compilation error
Motti
Thanks, fixed. 15char
Andrew Keeton
+13  A: 
 #ifdef NOOP       
     #define conditional_noop(x)   
 #elif

nothing!

Toad
I could not compile it this way. The problem is that I used #elif istead of #else. Now got it right. Thanks.
mezhaka
you are right... I just copied that from your example.
Toad
+4  A: 

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

Justin
+1  A: 

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)
The `do-while` trick has nothing to do with the age of the compiler.
avakar
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
+8  A: 

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)
#else       
    #define conditional_noop(x) std::cout << (x)   
#endif

Have fun coding!

Andrew
+5  A: 

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
+2  A: 

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.

GMan
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
+2  A: 
#ifdef NOOP
    static inline void conditional_noop(int x) { }
#else 
    static inline void conditional_noop(int x) { std::cout << x; }
#endif

Using inline function avoid 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 a non defined variable. This will eventually prevent you from getting compiler errors when you'll turn the NOOP flag on.

Nicolas Viennot
+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
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).
mos