Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force g++ to compile c++11 standard only?

Tags:

c++

c++11

g++

std::vector<bool>::emplace_back is available only since C++14. However, with my g++ 5.4.0 it compiles ok even if I specify -std=c++11.

When I compile the same code with g++ 4.8.4, it fails. Is there a way how to convince g++ to strictly check the selected standard?

Note: I already use -pedantic -Wextra -Wall.

Example test.cpp:

#include <vector>

int main()
{
    std::vector<bool> v;
    v.emplace_back(true);
    return 0;
}

Compile with g++ -std=c++11 test.cpp -o test. With g++ 5.4.0 compiles ok, g++ 4.8.4 fires:

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);
      ^
like image 917
Mi-La Avatar asked Aug 09 '19 07:08

Mi-La


1 Answers

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)

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

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
    

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

like image 153
lubgr Avatar answered Nov 15 '22 18:11

lubgr