Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I remove a C-style cast from a #define so I can use it in a preprocessor #if?

I would like to use the following preprocessor defines:

[3rd party header (cannot modify)]

#define SWCI_VERSION_MAJOR              (unsigned char) 4
#define SWCI_VERSION_MINOR              (unsigned char) 16

When they are compared in this way:

[my implementation]

#if SWCI_VERSION_MAJOR >= 4 && SWCI_VERSION_MINOR >= 16

Then I get:

fatal error C1017: invalid integer constant expression

I have noticed that if I define them without (unsigned char) the directive will be accepted, but I have no access to the defines so I would like to workaround the issue if possible.

like image 872
j4nSolo Avatar asked Feb 24 '16 13:02

j4nSolo


2 Answers

You can get this to work with a little preprocessor magic. Due to the way the preprocessor applies macros, you can sometimes do some modifications by using multiple macro levels. Boost.Preprocessor exploits this behavior. This code takes advantage of the fact that (unsigned char) looks like can be made into a macro invocation by prepending the macro name X which evaluates to nothing, leaving only the trailing number.

#define SWCI_VERSION_MAJOR              (unsigned char) 4
#define SWCI_VERSION_MINOR              (unsigned char) 16

#define X(unused)
#define APPLY(x) x

#define MAJOR (APPLY(X SWCI_VERSION_MAJOR))
#define MINOR (APPLY(X SWCI_VERSION_MINOR))

#if MAJOR >= 4 && MINOR >= 16
#error "Version is greater or equal to 4.16"
#endif

See https://goo.gl/GOsLDL for an example of the #if evaluating true and printing the #error message I added.

like image 116
Kurt Stutsman Avatar answered Nov 04 '22 12:11

Kurt Stutsman


Maybe using a constexpr function will do the trick? Something like

constexpr bool version_supported(const char major, const char minor)
{
    return major >= 4 && minor >= 16;
}
constexpr VERSION_SUPPORTED = version_supported(SWCI_VERSION_MAJOR, SWCI_VERSION_MINOR);
like image 39
Vorac Avatar answered Nov 04 '22 12:11

Vorac