[cmake-developers] Compiler feature extensions by default
Stephen Kelly
steveire at gmail.com
Thu May 29 12:50:31 EDT 2014
Hello,
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:
http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/9812
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:
http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/8115/focus=8193
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:
http://msdn.microsoft.com/en-us/library/34h23df8.aspx
http://msdn.microsoft.com/en-us/library/0k0w269d.aspx
http://stackoverflow.com/questions/18771299/does-msvc-mishandle
However, a counter-point is that it's unofficially considered harmful:
http://clang-developers.42468.n3.nabble.com/MSVC-Za-considered-harmful-td4024306.html
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:
https://github.com/llvm-mirror/clang/commit/3fe198bf0d61
and the use of the option was removed too:
https://github.com/llvm-mirror/clang/commit/a08e7bc74b56
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:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40278
[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:
https://lists.launchpad.net/kicad-developers/msg11843.html
>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
http://sourceforge.net/p/mingw/bugs/2046/
http://sourceforge.net/p/mingw/mingw-org-wsl/ci/088538f717bbafc5079940f3df298172a38ec4c1/
http://ehc.ac/p/mingw/bugs/2200/
https://github.com/mozilla/rust/issues/10893
https://github.com/llvm-mirror/clang/commit/a82a9c0cfc
https://github.com/llvm-mirror/llvm/commit/5de64fcb5e
http://llvm.org/bugs/show_bug.cgi?id=18847
https://github.com/llvm-mirror/llvm/commit/3f06e3f55fb
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
http://pic.dhe.ibm.com/infocenter/lnxpcomp/v121v141/index.jsp?topic=%2Fcom.ibm.xlcpp121.linux.doc%2Flanguage_ref%2Fcpp0x_exts.html
http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/9812
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.
Thanks,
Steve.
More information about the cmake-developers
mailing list