如何强制g ++仅编译c ++ 11标准?

Mi-*_*-La 10 c++ g++ c++11

std::vector<bool>::emplace_back可用的唯一的,因为C ++ 14。但是,对于我的g ++ 5.4.0,即使我指定,它也可以编译-std=c++11

当我使用g ++ 4.8.4编译相同的代码时,它将失败。有没有办法说服g ++严格检查所选标准?

注意:我已经使用了-pedantic -Wextra -Wall

范例test.cpp

#include <vector>

int main()
{
    std::vector<bool> v;
    v.emplace_back(true);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

用编译g++ -std=c++11 test.cpp -o test。使用g ++ 5.4.0编译正常,g ++ 4.8.4触发:

test.cpp: In function ‘int main()’:
test.cpp:6:7: error: ‘class std::vector<bool>’ has no member named ‘emplace_back’
    v.emplace_back(true);
      ^
Run Code Online (Sandbox Code Playgroud)

lub*_*bgr 7

This is related to libstdc++ that ships with gcc. In libstdc++, bits/vector.tcc, you have the std::vector<bool> specialization with

#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
template<typename... _Args>
// ... more stuff
vector<_Tp, _Alloc>::emplace_back(_Args&&... __args)
Run Code Online (Sandbox Code Playgroud)

The preprocessor branch enables the member function for C++11. In libc++ (the standard library implementation within the Llvm project), it's different:

#if _LIBCPP_STD_VER > 11
template <class... _Args>
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VISIBILITY reference emplace_back(_Args&&... __args)
#else
_LIBCPP_INLINE_VISIBILITY void      emplace_back(_Args&&... __args)
#endif
Run Code Online (Sandbox Code Playgroud)

so here, emplace_back is only defined with a standard beyond C++11. You cannot do much about it, but I see two options.

  1. To achieve strict conformance to C++11, not only compile with g++, but also with clang++. clang uses libc++ by default on MacOS, and on Linux you can pass some flag to enforce that (otherwise, it uses libstdc++), which does complain about emplace_back with -std=c++11. Then use the results of compiling with clang to adjust your sources that are otherwise built with gcc.

  2. Compile with gcc, but tell the compiler to use libcxx. From here, this also complains:

    g++ -std=c++11 -nostdinc++ -I /path/to/libcxx/include -nodefaultlibs \
        -lc++ -lc++abi -lm -lc -lgcc vecbool-emplace_back.cpp
    
    Run Code Online (Sandbox Code Playgroud)

I would go with option 1, because it hardens your program in different ways, too, not only standard compliance. Also, option 2 is cumbersome.

  • Clang并不总是使用libc ++,您可能需要询问它(-stdlib = libc ++)。默认情况下,这里使用libstdc ++。 (2认同)