I was struggling to find an answer amoung many that refer to this topic on SO, but here's some seemingly innocent looking code that fails to compile when F
is not a defined macro,
int main() {
#if defined(F) && F(0, 2, 0)
return 0;
#endif
return 1;
}
The problem, according to this section of the GCC manual is that inside #if
expressions "all macros in the expression are expanded before actual computation of the expression’s value begins", so this in an invalid check, since when F
is undefined, I see,
test.cpp:2:20: error: missing binary operator before token "("
#if defined(F) && F(0, 2, 0)
^
My question: is the only way to correctly do this check like so?
int main() {
#if defined(F)
#if F(0, 2, 0)
return 0;
#endif
#endif
return 1;
}
I find this quite ugly and unintuitive, so I'm hoping there's a nicer way to do such things in the preprocessor.
Assuming your F
macro is defined in some header file, you could place the following code somewhere between the include and its first usage:
#ifndef F
#define F(a,b,c) 0
#endif
Or another reasonable default. That's a common solution for your problem. Another is to not allow such macros to be not defined, but require either the default value or whatever it's expected to do. This latter approach is a bit safer for e.g. configuration files, as it makes clear the author did consider the macro and intentionally picked a value (i.e. he did not just forget to define it). It's also easier if the definition is in the same file.
Your test would then just be:
#if F(0, 2, 0)
Avoiding the nested condition (which would cause additional trouble if there was an #else
required somewhere.
Two words of advise:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With