7

Compiler vendors have been adopting C++11 features piecemeal, which was predictable, as many of them are not easily implemented.

The standard way for reporting which spec the compiler fully supports is via the __cplusplus predefined macro. However, major vendors are reporting __cplusplus = 199711L, meaning they are only fully supporting C++98 (eg. MSVC14). This (presumably) means that they do not fully support the C++11 spec, even though they may have implemented a lion's share of the functionality.

I would like to start using C++11 features, when they are available (and fallback to existing code when they are not). However, my code must support many compilers, including proprietary compilers which I may not have access to use. Is there any standard way to know which C++11 features are available from a compiler, without knowing specifically which compiler is being used? (if a compiler behaves in a non-standard way, then it is acceptable for the detection behavior to be incorrect).

NOTE: This question is a generalization of my question 'Availability of static_assert c++11', which was not very well received, because I think my motivation was misunderstood.

Community
  • 1
  • 1
MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78
  • 4
    gcc has a different value for `__cplusplus` depending on `-std=...`. Google for wg21+sg10 for recommended feature macros (not supported by VS). Boost, cmake and others also provide ways to detect available features. – Marc Glisse May 16 '15 at 16:09
  • @MarcGlisse (and answerers) Thanks for the info on gcc (did not know that - I generally work with VS). However, it is a a specific compiler, I want to know about detecting availability in general. – MuertoExcobito May 16 '15 at 16:14
  • @MuertoExcobito You cannot detect the "availability of C++11 features" from source. You need to look at the compiler's documentation, online or in the manual. – vsoftco May 16 '15 at 16:17
  • Recent versions of [CMake allow quite powerful feature detection on compilers](http://www.cmake.org/cmake/help/v3.2/manual/cmake-compile-features.7.html). – ComicSansMS May 16 '15 at 16:17
  • @vsoftco But, as I said, I might not have access to every compiler that my code will be compiled on. – MuertoExcobito May 16 '15 at 16:27
  • You would then need an external tool, like CMake. You cannot via macros. – vsoftco May 16 '15 at 16:30

3 Answers3

5

You might be interested in feature test macros, which enable you to test for specific C++11, C++14 or even C++17 features, such as __cpp_static_assert, __cpp_lib_make_unique or __cpp_variable_templates. Clang and GCC already support this, see a live demo.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • The [latest proposal for this](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4440.html) even includes suggestions for macros for upcoming C++17 features. – ComicSansMS May 16 '15 at 16:28
  • Gcc supports them as well, but not Visual Studio AFAIK, so that's going to be hard for the OP. – Marc Glisse May 16 '15 at 16:28
  • @MarcGlisse Yeah, GCC does - adjusted my example. I still think this is noteworthy, even though the OP might be using VC++- – Columbo May 16 '15 at 16:31
  • This looks very much in line what I was looking for. Obviously it is not yet available on all compilers, but, is going to be standard. Going to check out various compiler support, but I will likely accept this answer. – MuertoExcobito May 16 '15 at 16:54
  • So, it looks like MSVC doesn't have support for these, which is unfortunate. However, it still seems like the most standard compliant way to achieve what I'm looking for (so I am accepting it). For compilers that don't support this feature, but still support C++11 (or 14/17) features that I'd like to use, I can define the standard ones on a compiler-by-compiler basis in a 'configuration' header. Thanks! – MuertoExcobito May 17 '15 at 01:48
1

g++/clang++ do not have C++11 enabled by default, not even the latest versions. Whenever you compile with g++ using -std=c++11, your macro __cplusplus will have the expected value.

VS seem to have all features enabled by default, thanks @Comic, but it is not updating the macro since it is not yet fully C++11 compliant.

As far as detecting "C++11 availability" for a generic compiler, I am not aware of any portable way of doing it, unless you check for the __cplusplus macro. But, as you observed, the macro may not be implemented for some compilers by default (as is the case for g++/clang++), or not implemented at all (VS). Your only choice at this stage seem to be an external tool like CMake, which can detect the compiler, and conditional on the compiler type CMake can then define some macro which you can check in your code to enable C++11.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • `std=c++11` doesn't apply to Visual Studio though does it, only `g++`? – MuertoExcobito May 16 '15 at 16:16
  • @MuertoExcobito no, there should be a specific flag for VS also (I don't use it and I do not know it). – vsoftco May 16 '15 at 16:17
  • @MuertoExcobito Not VS, but not only gcc. Others use the flag too (e.g. clang++) – juanchopanza May 16 '15 at 16:18
  • 7
    Visual Studio [does _not_ need a compile option to enable C++11 features](http://stackoverflow.com/questions/5121529/how-to-enable-c0x-features-in-visual-studio-initializer-lists-support). All available features are always enabled and cannot be switched on or off. – ComicSansMS May 16 '15 at 16:19
  • @Comic thanks, I corrected the answer. I am using g++ and didn't know about VS. – vsoftco May 16 '15 at 16:25
  • @vsoftco gcc does not enable C++11 by default, but compiles some features from it even without `-std=c++11` (and emits a warning about lack of the flag). – HolyBlackCat May 16 '15 at 16:32
  • 2
    I think that's because it uses gnu c++11 extensions by default, but the macro is not updated – vsoftco May 16 '15 at 16:33
-1

I think many of the C++11 features are available on GCC 4.8 also. Compile your program with -std=c++11 option.

I think some of the C++11 features were in GCC 4.6.3 as well. Compile option to enable it -std=c++0x .

Nipun Talukdar
  • 4,975
  • 6
  • 30
  • 42
  • GCC 4.7 included a significant portion of C++11 as well. – Adam May 16 '15 at 16:10
  • IIRC gcc 4.8 has all the C++11 language features. Most of them were available in gcc 4.7. – juanchopanza May 16 '15 at 16:11
  • @Adam yes. I think only the compile option flag is -std=gnu++11 , not c++11 on GCC 4.8 – Nipun Talukdar May 16 '15 at 16:14
  • You're basically making stuff up. It isn't too hard to check this. – juanchopanza May 16 '15 at 16:17
  • @MarcGlisse Just checked. GCC 4.9 doesn't enable C++11 by default. Thanks for pointing it out. – Nipun Talukdar May 16 '15 at 16:18
  • 1
    I guess latest release enabled them by default , for rest you'll have to pass -std=c++1y. – Abhinav Gauniyal May 16 '15 at 16:21
  • 3
    @AbhinavGauniyal No, `-std-c++11` (or `-std=c++0x` for older versions without full supprt) for C++11. What is it with people making wrong statements today? – juanchopanza May 16 '15 at 16:22
  • @AbhinavGauniyal please don't guess (there are plans to make C++11 the default in g++-6.1 next year...). – Marc Glisse May 16 '15 at 16:22
  • 1
    @AbhinavGauniyal It does not stand for C++11. `y!=1`. – juanchopanza May 16 '15 at 16:24
  • @juanchopanza yes I know , that's why I cleared you can write y=1 or 4 and so on. Although you can write y too. – Abhinav Gauniyal May 16 '15 at 16:25
  • 2
    @AbhinavGauniyal C++1y does not cover C++11. The order is C++0x, C++11, C++1y, C++14. C++11 was expected to be released before 2010, hence 0x, but it slipped and became C++11. – Dave May 16 '15 at 16:28
  • @AbhinavGauniyal That's why you said y = 1, 4...? Because `y!=1`? Please stop producing nonsense that will confuse newcomers. – juanchopanza May 16 '15 at 16:28
  • @juanchopanza & dave , I might be wrong here , can you provide me any resources for this? I thought c++1y meant enabling all features upto c++14. – Abhinav Gauniyal May 16 '15 at 16:30
  • 2
    @AbhinavGauniyal Yes, so if you want C++11 rather than C++14, you shouldn't use `-std=c++1y`, you should use `-std=c++11`. The values for `-std=` are described on [C Dialect Options](https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/C-Dialect-Options.html#C-Dialect-Options), where it will tell you that `-std=c++1y` means the same thing as `-std=c++14`. –  May 16 '15 at 16:36
  • 1
    @hvd thanks. I'll upvote for visiblity so that newcomers aren't misguided by my lame comment. – Abhinav Gauniyal May 16 '15 at 16:38
  • 1
    @AbhinavGauniyal feature-wise, C++1y does indeed cover C++11's feature-set. But it would be entirely wrong to think that C++1y can *mean* C++11. It doesn't - it means a superset of its features (and while I don't know the spec in detail, it's possible that some of the features of C++11 are changed in it in an incompatible way) – Dave May 16 '15 at 16:38
  • 1
    @dave , I did meant covering all feature set upto c++14 , didn't realized implementation might contain non-compatible changes. You're right :) – Abhinav Gauniyal May 16 '15 at 16:40