【问题标题】:How to force g++ to compile c++11 standard only?如何强制 g++ 只编译 c++11 标准?
【发布时间】:2019-12-16 21:42:30
【问题描述】:

std::vector<bool>::emplace_backavailable 仅从 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;
}

使用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);
      ^

【问题讨论】:

  • 缺少vector&lt;bool&gt;::emplace_back 并不是对符合实现的约束。它是对符合 programs 的约束。一个实现可以在它认为合适的时候在标准类中定义额外的成员。
  • 相关(相同观察):std::vector<bool>::emplace in C++11
  • @n.m.标准在哪里说实现可能包括其他成员?
  • @hyde: Demo 带有 OP 的代码(编辑后)。
  • @Ayxan 在 C++11 Stadnard 中,它也在脚注 188 中:实现还可以定义其他成员函数,否则这些成员函数不会被有效的 C++ 程序调用。我>

标签: c++ c++11 g++


【解决方案1】:

这与 gcc 附带的 libstdc++ 有关。在libstdc++bits/vector.tcc 中,您拥有std::vector&lt;bool&gt; 专业化

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

预处理器分支启用 C++11 的成员函数。在libc++(Llvm 项目中的标准库实现)中有所不同:

#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

所以在这里,emplace_back 仅使用 C++11 以外的标准定义。您对此无能为力,但我看到了两种选择。

  1. 要严格遵守C++11,不仅要使用g++编译,还要使用clang++编译。 clang 在 MacOS 上默认使用 libc++,在 Linux 上你可以传递一些标志来强制执行(否则,它使用 libstdc++),它确实抱怨 emplace_back-std=c++11。然后使用clang 编译的结果来调整你的源代码,否则这些源代码是用gcc 编译的。

  2. 使用gcc 编译,但告诉编译器使用libcxx。来自here,这也抱怨:

    g++ -std=c++11 -nostdinc++ -I /path/to/libcxx/include -nodefaultlibs \
        -lc++ -lc++abi -lm -lc -lgcc vecbool-emplace_back.cpp
    

我会选择选项 1,因为它也会以不同的方式强化您的程序,而不仅仅是标准合规性。另外,选项 2 很麻烦。

【讨论】:

  • 这个。没有编译器是 100% 符合的。如果您想针对此类不可移植行为强化代码,则应使用多个编译器进行构建。
  • Clang 并不总是使用 libc++,您可能需要询问 (-stdlib=libc++)。这里默认使用 libstdc++。
  • 其实我们是用g++、MinGW和MSVC编译的。我们也考虑过 clang,但还没有时间设置自动构建。
  • 谁负责 libstdc++,谁负责 libc++? libstdc++ 是 g++ 的“一部分”吗? libc++ 是从哪里来的?
  • @Mi-La GNU 项目用于 libstdc++,LLVM 项目用于 libc++。
猜你喜欢
  • 2012-05-08
  • 1970-01-01
  • 1970-01-01
  • 2011-12-20
  • 2014-04-12
  • 2012-01-14
  • 2016-02-28
  • 1970-01-01
相关资源
最近更新 更多