If an old C++ compiler doesn't implement a new keyword, is it wrong to define it away?

Viewed 87

I am maintaining a library that is still supported on older compilers, one of which is Visual C++ 2013 on Windows. So far we've been extremely conservative and stuck to C++03; we're now moving to C++11. VC++2013 supports most of the newer features, but it doesn't recognize noexcept.

Of course the canonical way to add it to the code would be to define something like

#if (the compiler does not support it)
    #define NOEXCEPT
#else
    #define NOEXCEPT noexcept
#endif

and then use it like

void f() NOEXCEPT;

The downside, of course, is that we're sprinkling macros around the code.

However, it occurred to me (possibly suggested by a little guardian devil on my shoulder) that I could also write

#if (the compiler does not support it)
    #define noexcept
#endif

after which I could write

void f() noexcept;

and the keyword would be used correctly by newer compilers and defined away on the older ones.

This worked (as in, it compiled successfully) but, well, I'm feeling kind of dirty — and I'm not sure I should. Of course, defining away a keyword is forbidden under the standard that defines it; but is it still so if the compiler doesn't fully support the standard, or am I in some kind of grey area?

1 Answers

Since it wasn't a keyword in the old standards, you were, and technically still are allowed to define such macro when targeting the old standard.

P.S. The typical definition for pre-C++11 is to use throw() in place of noexcept.

P.P.S. Note that in the case of noexcept, the macro doesn't work for declarations such as

void foo() noexcept(false);
bool bar = noexcept(foo());

So, these statements cannot be so easily made backwards compatible. Given the inability to support all use cases of noexcept, the usage of different name for the macro may help to avoid confusion.

Related