Jaeya
Jaeya

Reputation: 141

C++: ignore a declaration

I am using C++ preprocessor macros to selectively ignore some code blocks for testing purposes, e.g.

#ifdef __SAFE
    #define note 
    #define ensure(X) if(X) {} else 
#else
    #define note while(false)
    #define ensure(X) while(false)
#endif

Intuitively, note executes some code (usually setting some guard variable) and ensure executes the next code block if the condition is violated. With these macros, I can write:

note { var = true }
ensure(var == true) { throw new std::exception; }

and the code will compile whether __SAFE is defined or not (and the compiler will most likely get rid of the dummied out code). This is nice because it behaves essentially as an extension of the C++ language.

I would also like to similarly skip some data member declarations in classes when __SAFE is undefined. The tricks above do not work anymore, since flow control is disallowed inside a class declaration. I would like to declare some macro guard for which the class:

class A {
guard int x;
}

contains member int x only when __SAFE is defined.

Possible solutions:

I know the C++ preprocesor is not very powerful. I would just like to know if there is an aesthetically pleasant solution; otherwise I will simply use the latter option.

Upvotes: 1

Views: 920

Answers (1)

Massimiliano Janes
Massimiliano Janes

Reputation: 5624

Since C++11, you can use a template alias, something like:

struct A {
  guarded<int> x;
};

where guarded is defined as:

#ifdef YOUR_SAFE_MACRO

template<typename T>
using guarded_impl = T;

#define guarded guarded_impl

#else

template<typename T>
struct guarded_impl {};

#define guarded static guarded_impl

#endif

this has also the bonus of giving a linker error if the variable is ODR-used when YOUR_SAFE_MACRO is off (if on, the dummy static variable is still there, but should be optimized out at link time if unused).

You can do this in < C++11 as well, but it will be slightly more verbose.

That said, I guess note, ensure and guard are too common names to be used as macros and still hope no name clashing will occur, so I'd strongly advise against such a thing ( you've been warned :) )

Moreover, people reading your code will get confused by having a static hidden in a macro that looks like a template ... a good'ol #ifdef would be a better solution in my opinion.

Upvotes: 3

Related Questions