Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there way to check the type of a preprocessor symbol value in C/C++

Parts of my code depend on the value of a preprocessor symbol:

int a()
{
#if SDK_VERSION >= 3
    return 1;
#else
    return 2;
#endif
}

The comparison depends of the value of SDK_VERSION. It is expected to be a integer or something that compares to a integer, in this case, 3. If SDK_VERSION is something that cannot be compared to a integer, there will be a compile error.

Is there a way to abort the compilation if SDK_VERSION is not of an expected type? For example:

#if type(SDK_VERSION) != int  # Does not compile, I know
#error "SDK_VERSION must be an integer."
#endif
like image 623
GDICommander Avatar asked Jan 23 '12 19:01

GDICommander


2 Answers

Use template to generate such error:

template<typename T> struct macro_error;

template<> struct macro_error<int> {};

template<typename T> void check(T) 
{ 
   macro_error<T> SDK_VERSION_must_be_int; 
}
int ignored = (check(SDK_VERSION), 0);

This code would generate compilation error, having the following string in it, if the SDK_VERSION is not int:

SDK_VERSION_must_be_int

See these demo:

  • http://ideone.com/mWXIm (Error : #define SDK_VERSION 1.0)
  • http://ideone.com/CRjXN (Ok : #define SDK_VERSION 1)

And also notice the error message in the first case. It prints this:

prog.cpp:9: error: ‘SDK_VERSION_must_be_int’ has incomplete type
prog.cpp:9: warning: unused variable ‘SDK_VERSION_must_be_int’
like image 195
Nawaz Avatar answered Oct 13 '22 23:10

Nawaz


Nope. The reason is that the preprocessor symbol doesn't have a type at all.

Preprocessor symbols are best thought of as being just barely more than a string. C's type system doesn't really exist until the compilation step, which happens after the preprocessor has had its go.

like image 25
Matt Avatar answered Oct 13 '22 23:10

Matt