How to Check For C++11 Support

How do I check for C++11 support?

Quick history

When this question was asked in February 2011, support for C++11 was inconsistent. Compilers needed time to catch up to the standard, so in the meantime, they released with partial support. For example, a compiler might have implemented variadic templates, but not auto.

If you had code that depended on a subset of C++11 features, you didn't have a standard way of asking the compiler whether it supported them specifically.

You could check for overall C++11 support with #if __cplusplus >= 201103L, but:

  • That constant and its meaning weren't technically official until the standard was accepted later, in August 2011.
  • This was too coarse. Compilers probably only set __cplusplus to 201103L once they had full feature support—and no one had full feature support yet. So, if you used this, you would unnecessarily reject most or all of the compilers that people would want to use to compile your code.

One pragmatic solution was to use the third-party Boost.Config library, which maintained a bunch of feature test macros. Boost.Config's maintainers kept track of which compilers supported which features, and updated the macros accordingly for each Boost.Config release.

(This stuff about Boost is based on an early, now-deleted answer from @James McNellis.

Today

C++11

Today, there's a version of every major compiler that supports the whole C++11 standard. .

If your code requires any of C++11, it's now reasonable to require that the compiler supports all of C++11. So, use #if __cplusplus >= 201103L. (See @Paulo M's answer for a standards reference for this macro.) But beware that there are complications with MSVC—see @Donald Duck's answer.

Beyond

Since C++20, in addition to the coarse-grained __cplusplus macro, you can also #include <version> to get a bunch of feature test macros. This is basically a standards-based alternative to Boost.Config.

According to this answer from Jarryd, these macros are actually available in at least some 2016-era C++14 compilers.

Compiling C++11 with g++

Flags (or compiler options) are nothing but ordinary command line arguments passed to the compiler executable.

Assuming you are invoking g++ from the command line (terminal):

$ g++ -std=c++11 your_file.cpp -o your_program

or

$ g++ -std=c++0x your_file.cpp -o your_program

if the above doesn't work.

How to detect C++11 support of a compiler with CMake

If you have CMake version 3.1.0 or later you can detect what C++ features
your C++ compiler supports

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
message("Your C++ compiler supports these C++ features:")
foreach(i ${CMAKE_CXX_COMPILE_FEATURES})
message("${i}")
endforeach()

But normally you don't need to use the CMake variable CMAKE_CXX_COMPILE_FEATURES in your CMake scripts. Instead there are two ways of how to tell CMake under which C++ standard your C++ files should be compiled, either by
specifying the C++ standard explicitly or by specifying the required C++ features and let CMake induce the C++ standard. CMake will make sure the C++ compiler is invoked with the correct command line flags (e.g. -std=c++11).

1. Specifying the C++ standard explicitly

You could specify the C++ standard explicitly, by setting the CMake properties
CXX_STANDARD
and
CXX_STANDARD_REQUIRED for your CMake target.

$ cat /tmp/src/CMakeLists.txt
project(foobar CXX)
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
add_executable(prog main.cc)
set_property(TARGET prog PROPERTY CXX_STANDARD 11)
set_property(TARGET prog PROPERTY CXX_STANDARD_REQUIRED ON)
$ cat /tmp/src/main.cc
int main() {
return 0;
}
$ mkdir /tmp/build
$ cd /tmp/build
$ cmake /tmp/src
-- The CXX compiler identification is GNU 4.8.2
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build
$ make VERBOSE=1 | grep main.cc | grep -- "-c"
/usr/bin/c++ -std=gnu++11 -o CMakeFiles/prog.dir/main.cc.o -c /tmp/src/main.cc
$

2. Specifying the required C++ features and let CMake induce the C++ standard

You could use the CMake command target_compile_features to specify the C++ features that are made use of in your CMake target. From this list CMake will induce the C++ standard to be used. The CMake global property CMAKE_CXX_KNOWN_FEATURES lists the C++ features you can choose from.

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
message("Your CMake version supports these C++ features:")
get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
foreach(i ${known_features})
message("${i}")
endforeach()

For example, this C++ program with the filename main.cc makes use of the C++11 features:
cxx_strong_enums, cxx_constexpr, cxx_auto_type

#include <cstdlib>

int main(int argc, char *argv[]) {
enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
constexpr float a = 3.1415f;
auto b = a;
return EXIT_SUCCESS;
}

This CMakeLists.txt file would build it

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
add_executable(foobar main.cc)
set(needed_features
cxx_strong_enums
cxx_constexpr
cxx_auto_type)
target_compile_features(foobar PRIVATE ${needed_features})

How can I know if my compiler support XXXX C++11 feature?

Boost actually has a wide range of such macros available. You could use that. Otherwise, the only way is to essentially check the compiler's version and use your knowledge of the features supported in that version to decide if a feature is available or not.

Essentially, what Boost does, except manually.

Checking C++11 support for regex: not supported

Regex support was added in gcc 4.9
- @Bill-Lynch

You have two options:

  • Install a newer compiler.
  • Go through the code and replace all regexes with equivalent functions.

check if c++11 features are used or not

Reposting my comment.

Modern compilers got -std=c++11 as default. Old ones need to explicit say we want c++11 by -std=c++11. You can explicit choose any standard you want. So use -std=c++03 gives you error on all C++11 construct.

But this is no whole story. Some code can behave in different way in C++03 and C++11 but still compile! For example static initialization is thread-safe only in C++11 so in C++03 you will get code which will compile but be bugged. Te be sure you need to review whole code with person who perfectly know C++03, C++11 and theirs differences.

Probably you can support this work with tools for static code analysis but to be 100% sure you need to review it...

Availability of C++11 features

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.



Related Topics



Leave a reply



Submit