[cmake-developers] Compiler feature extensions by default

Stephen Kelly steveire at gmail.com
Thu May 29 12:50:31 EDT 2014


Part of the design of the compile features concept is that it may be used to 
require compiler extensions. The extensions are enabled by default for GNU 
and Clang - that is, the option -std=gnu++98 is implied. Passing -std=c++98 
disables the extensions, as do other language standard dialect variants such 
as -std=c++11 (as opposed to the option -std=gnu++11). Some other compilers 
implement similar options:


Thus, the use of target_compile_features or the CXX_STANDARD target property 
can result in failure to compile if the extensions are used in the code. 
This is documented and can be fixed by the user either by setting 
CXX_EXTENSIONS, listing the feature requirement on the compiler extensions 
if known to CMake (none so far). This was the conclusion reached here:


1) This can be interpreted as inconsistent with how MSVC compile features 
are planned/designed to behave.

For consistency, it could be justified to add /Za to MSVC command lines:


However, a counter-point is that it's unofficially considered harmful:


Choice quotes:

  1) It's just that /Za is flaky, and it's rarely used which means that even 
less code exercises it.
  2) The common problem is that standard library headers shipping with the 
compile *should* have access to the extensions.

The move emulation referenced by Benjamin Kramer was removed, as the Clang 
developers require a more recent MSVC version already:


and the use of the option was removed too: 


2) My code can be portable while not disabling extensions to allow third-
party headers to take advantage of them.

Regarding quote (2), I find a few uses of __STRICT_ANSI__ in my libstdc++ 
headers, but none in my libcxx headers. It makes sense to me that std 
library releases, which are tied to the compiler release, can take advantage 
of compiler extensions if available without affecting the portability of my 
code. The same is true for headers of third-party libraries I use. At least 
Boost::Math is affected by whether __STRICT_ANSI__ is defined, relating to 
int128 use.

3) Disabling extensions is not well-tested and can cause bugs not obviously 
caused by disabling them

Quote (1) above relates to this. Here is a similar quote for GCC:


 [the issue] appears also for -std=c++98 vs -std=gnu++98, but often it's not 
noticed because people don't use -std=c++98 very often.

The fact that -std=c++98 (and -std=c++11 to some extent) is not often used 
means that bugs exposed might not obviously be caused by it.

This is also a point made here, which I think makes some sense:


>From the point of view of the CMake interface, requiring a feature by using 
target_compile_features is a more obvious change than the implicit disabling 
of extensions.

4) Platform support headers may depend on compiler extensions

This is also a cause of surprise, particularly if the platform affected is 
not one primarily used by the developers.

For example, off_t not defined in mingw with std=c99

I could not reproduce the problems with the MinGW I have, and I asked Rafael 
Espíndola if he had any more information about what version of MinGW would 
be needed etc, but he had no more information. I don't know that it is still 
a problem, but I suspect it is.

5) The XL compiler has no group compile option for 'non-extended' C++11


So, for that compiler, the only option is the equivalent of -std=gnu++11, 
which is not consistent with the GNU/Clang behavior.

For the above reasons of consistency, having an interface in CMake which 
does not unnecessarily change default behavior of compilers, 'least 
surprise', allowing optimal content in third-party headers, and having an 
interface in CMake which does not implicitly increase exposure to bugs, I 
recommend we change C{,XX}_EXTENSIONS to 'on-by-default'.

The user may still set it to FALSE explicitly in order to use a possible 
non-extended compile option where available. Specifically, if set to FALSE, 
that would mean CMake would use -std=c++11 instead of -std=gnu++11 with GNU 
or Clang.



More information about the cmake-developers mailing list