[cmake-developers] Compiler features/extensions remaining/future issues

Stephen Kelly steveire at gmail.com
Sat May 31 09:17:59 EDT 2014


Hi,

Here is a dump of some notes I have accumulated regarding compile features.

1) Extensions requiring compile options

The target_compile_features interface is designed to allow use with compiler 
extensions such as gnu_cxx_typeof and msvc_cxx_sealed. The extensions 
discussed so far have been extensions which happen to depend on 'big switch' 
options like /Za and -std=gnu++11 vs -std=c++11. 

However, there are other cases.

Clang supports msvc_cxx_sealed on all platforms if the -fms-extensions 
option is passed:

 $ clang++ -fms-extensions main.cpp                                                                                                                                     
 main.cpp:353:10: warning: 'sealed' keyword is a Microsoft extension [-
Wmicrosoft]                                                                                                                                  
 struct A sealed {};                                                                                                                                                                                                
         ^                                                                                                                                                                                                         
 1 warning generated.                         


It might make sense to allow passing additional options for compiler 
extensions which need them. Eg

+set(_cmake_feature_test_msvc_cxx_sealed "${Clang34}")
+set(_cmake_feature_test_msvc_cxx_sealed_compile_option "-fms-extensions")

The patch at

 https://www.mail-archive.com/cfe-commits@cs.uiuc.edu/msg97160.html 

requires -fplan9-extensions. I don't know if it enables any relevant 
features, but I note it for completeness.


2) Incompatible features 

Two features known to CMake might be incompatible. 

For example, the cxx_auto_type feature (c++11) conflicts with a 
cxx_auto_storage_type_specifier (c++98). In this case, it is a non-issue 
because variables have automatic storage duration by default anyway, and the 
feature of 'auto as a storage type specifier' is deprecated in c++11 partly 
due to non-use, so no CMake user is likely to have a use for such a thing.

Another example is exported templates, which are removed from c++11:

 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf
 (Why we can't afford ``export``)

which may conflict with the cxx_extern_templates feature (c++11). However, 
only EDG implemented the exported templates feature, and it was only made 
available for use with the Comeau compiler. I don't think it makes sense to 
add it as a known feature to CMake.

So for now, I don't think incompatible features is an issue, but it may 
become one in the future, and the CMake implementation would need some way 
to handle that.

Another way that incompatible features could arise is if a compiler supports 
a msvc_cxx_foo feature and a gnu_cxx_bar feature which may not be used 
together because of compile options which may not be used together.


3) Extensions which may become standard

GNU 4.9 supports explicit template parameter syntax for generic lambdas:

 https://gcc.gnu.org/gcc-4.9/changes.html
 https://gcc.gnu.org/ml/gcc/2009-08/msg00174.html

 int main()
 {
   // a functional object that will add two objects
   auto add = [] (auto a, auto b) { return a + b; };

   // Allowed by GNU 4.9 with -std=gnu++1y (and -std=c++1y)
   // Adds only like-type objects
   auto add_constrained = [] <typename T> (T a, T b) { return a + b; };

   // Variadics not allowed:
 //   auto num_args = [] <typename T...> (T... t) { return sizeof(t...); };

   int ret;
   ret = add(3, -3);
   ret = add_constrained(3, -3);
   ret = add(3.0, -3);
   // error: no match for call to ‘(main()::<lambda(T, T)>) (double, int)’
 //   ret = add_constrained(3.0, -3);
   return ret;
 }

Something like this might be added to the standard together with Concepts in 
c++17, as per section 5.4 of 

 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3418.pdf

So, today we might add a gnu_cxx_lambda_template_parameters feature to CMake 
supported by GNU 4.9, but we might add a cxx_lambda_template_parameters in 
the future which might subsume or might conflict with the gnu_ variant (if 
standard behavior is somewhat different).

I don't see any independent problem with this, but I just thought I'd point 
it out. It might lead to 'conflicting features', or we might decide it is an 
error to specify both gnu_cxx_lambda_template_parameters and 
cxx_lambda_template_parameters in that case.

See also cxx_inline_namespaces and GNU strong namespaces:

 https://gcc.gnu.org/onlinedocs/gcc/Namespace-Association.html#Namespace-Association

See also the Modules feature, which is going toward standardization and 
currently requires a compile option in the Clang implementation

 http://clang.llvm.org/docs/Modules.html

Also, I think GNU allows the c_restrict feature (C11) in c++ mode, which may 
become standardized in c++ in the future.


4) WG 21 standing document 6 (study group 10)

Just pointing this out for completeness:

 https://isocpp.org/files/papers/n4030.htm

Clang and CMake generally refer to 'cxx' instead of 'cpp', and I think it's 
ok for the features known to CMake to continue to have cxx_ prefixes.

The SD6 document might be a useful reference for naming things. 

Note though that there are some essential differences. Those recommendations 
use a single macro for the c++11 constexpr feature and for the c++14 relaxed 
constexpr feature

 __cpp_constexpr = 200704 (cxx_constexpr)
 __cpp_constexpr = 201304 (cxx_relaxed_constexpr)

As the CMake features are not differentiated in that way, some differences 
compared to that document will remain necessary.


5) Disabling features, aka 'Enabling' non-features

I could imagine adding a feature to control whether exceptions are allowed 
in compiled code. With GNU there is a -fno-exceptions option which may be 
passed to error on use of ``throw``. I believe with MSVC has something 
similar.

Would a cxx_no_exceptions feature be a reasonable fit into the compile 
features concept, with the corresponding compile option?

Something similar could be said for rtti.


6) target_compile_features as a universal feature interface

If compile features are to be linked in some way with compile options, the 
idea of using it for cxx_position_independent_code arises. We already have 
an interface in CMake for that, so I'm just listing this for completeness, 
and for consideration of how future similar interfaces should be handled. We 
might be able to think about that a bit now.

For example cxx_sse2 and cxx_avx features could be added which add 
/arch:SSE2 or /arch:AVX for MSVC, and -msse2 or -mavx for GNU

 http://stackoverflow.com/questions/661338/sse-sse2-and-sse3-for-gnu-c

This isn't something I think should definitely be done, but is something to 
think about.


7) Extending the compiler feature support matrix.

I'm finished with extending the feature support matrix for now. 

MSVC features are obviously missing, but someone else will have to add and 
maintain those, and try them out to find any issues similar to those 
recorded in comments for the GNU and Clang compilers such as discrepancy 
between documented and actual features, broken features etc.

Extending the feature matrix to past releases also should be done carefully 
(if at all). The c++11 standard evolved over almost a decade, things changed 
in that time, and compilers implemented intermediate versions in that time. 
For example, there are many versions of 'rvalue references' and MSVC does 
not yet implement the accepted version

 http://msdn.microsoft.com/en-us/library/hh567368.aspx#rvref

In this case, 'rvalue references v3' has a separate feature in CMake 
(cxx_defaulted_move_initializers), so it is likely not an issue, but someone 
extending support to that compiler or old releases of it, or old releases of 
other compilers would need to check things like that.

 http://rrsd.com/blincubator.com/bi_library/afio/
 "and auto-generate implicit move constructors when all member data types 
have move constructors (known in Microsoft as rvalue references v3.0)"

As well as consider whether 'pure bugs' in compiler releases are severe 
enough to disable the feature for that compiler. This is mostly an issue for 
older Clang/GNU releases  

 http://milianw.de/blog/c11-platform-support#comment-1401

and for MSVC releases (I recorded a few serious bugs at

 https://gitorious.org/cmake/steveires-cmake/source/0156b7f4:Modules/Compiler/MSVC-CXX-FeatureTests.cmake

)

We previously agreed to treat documented features as available, but as the 
compiler feature matrix is currently small, this decision has not yet had to 
be made concrete, and could be re-visited if someone had a need to do so.


8) Standard library features

It would be possible to somewhat-selectively record features of the standard 
library by including a stdlib header and check features of that by version. 

 http://thread.gmane.org/gmane.comp.compilers.clang.devel/22916/focus=22917
 
The GLIBCXX macro is not useful for version checking, but the compiler 
macros could possibly be tested instead in that case because of tight-
coupling

 http://stackoverflow.com/a/11925468/2428389

Standard library features are in-scope for the SD6 feature testing 
     
 https://isocpp.org/files/papers/n4030.htm
    
and as far as I know, it is in scope for Boost.Config too.

I'm not convinced they should be in scope for CMake however. There would be 
too many features drowning out other features (for each class/algorithm?, 
c++14 additions of constexpr

 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3470.html

etc). We could consider using the SD6 macros for std lib feature detection, 
but as those macros are designed to be defined in the header that contains 
the feature, we would end up having to compile a header which includes a 
large amount of std lib headers at the beginning of CMake time to record the 
features, which does not seem worth it.

So I'm not planning to investigate that further.


Thanks,

Steve.




More information about the cmake-developers mailing list