undefined behaviour and C++ language stability

Viewed 114

I was told that #defining language keywords is undefined behaviour. How does this play with the following facts:

  1. Users can #define names that are not keywords in their code.
  2. The language can get new keywords that used not to be keywords over time.
  3. Users should be able to compile old code with new compilers and get a compile-time diagnostic rather than undefined behaviour if any construct they used has ceased to be supported.

#3 is obviously my assumption but I consider this assumption essential as newer compilers tend to be better and "knowing the whole extent of the current law" is a theoretical legal assumption that does not apply to software developers, I hope (if the compiler assumed otherwise, it could replace any compile-time error in the code with whatever undefined behaviour it pleases).

3 Answers

#3 is not the case and has never been guaranteed by anyone. While the C++ committee does not like to create backwards incompatibilities that don't noisily break, they still sometimes do it.

You shouldn't expect a thing that you were not told to expect.

And yes, it's possible that adding a new keyword breaks silently for those who #defined that keyword. This is one of the many reasons why users are told to use ALL_CAPS for their #define names, since keywords will almost certainly not be in ALL_CAPS.

C++ standards are not fully backwards-compatible. That doesn't hold you back from using a modern compiler.

If you want to compile old code with a new compiler, you set the C++ version explicitely with a flag. For example, with GCC, the default C++ version varies with version. To set it explicitely, you use the -std option, e.g. std=c++11 or std=c++0x.

Then any keywords introduced after this version will not be in effect so you will not run into undefined behavior. If you would like to use the newer language features on the other hand, you need to go through the documented newly introduced keywords and some subtleties that changed and review your code accordingly.

#3 Users should be able to compile old code with new compilers and get a compile-time diagnostic rather than undefined behaviour if any construct they used has ceased to be supported.

This is a good thing to strive for, but there is technically no such guarantee.

#2 The language can get new keywords that used not to be keywords over time.

Yes. Because of desire to keep existing programs working, the standards committee is usually against introducing new keywords, but it does happen regardless.

For those cases where a new keyword is introduced, there is a trick to avoid name collisions (with high probability) with your macros: Use upper case. None of the C++ keywords with the exception of _Pragma use upper case, and this is likely to stay true in future. For other identifiers than macros, using keywords makes the program ill-formed, so you are guaranteed a diagnostic.

Related