g++、clang++、使用libboost的编译花絮——g++7成功时g++8编译失败;

Posted

技术标签:

【中文标题】g++、clang++、使用libboost的编译花絮——g++7成功时g++8编译失败;【英文标题】:Compilation tidbits on g++, clang++, using libboost -- g++8 compilation fails when g++7 succeeds; 【发布时间】:2018-08-15 12:31:20 【问题描述】:

我在 github repository 上有代码示例,并在 travis-ci 上创建了一个构建以便于复制。

最小、完整和可验证的示例

可能不是最小,但我相信它足够小

它使用 boost.interprocess 库 (boost::interprocess::managed_shared_memory) 创建一个共享内存区域,然后使用来自 boost 库的该区域分配器创建一个常规 STL unordered_map

代码是我当前封闭源代码库中的精简版本,灵感来自sehe 的问题std::unordered_map with boost::interprocess allocator in shared memory - drawbacks? 中的答案

#include <sys/mman.h>
#include <sys/syscall.h>
#include <functional>
#include <memory>
#include <unordered_map>
#include <string>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/shared_memory_object.hpp>

class Thing 
 public:
  volatile Thing *_parent;
  explicit Thing(Thing *parent) : _parent(parent) 
;

namespace ipc = boost::interprocess;
using Segment = ipc::managed_shared_memory;
using Manager = Segment::segment_manager;
template <typename T> using Alloc = ipc::allocator<T, Manager>;
template <typename K, typename V, typename KH = std::hash<K>, typename KEq = std::equal_to<K>>
using HashMap = std::unordered_map<K, V, KH, KEq, Alloc<void>>;
typedef HashMap<pid_t, Thing> ThingMap;

int main() 
        boost::interprocess::shared_memory_object::remove("test");
        Segment my_segmentipc::create_only, "test", 1ul<<40;
        Manager *my_manager = my_segment.get_segment_manager();
        ThingMap *my_map = my_segment.find_or_construct<ThingMap>("my_map")(my_manager);
        my_map->emplace(123, nullptr);
        printf("Hello world\n");
        return 0;

问题

1。 clang++ 需要安装g++

使用 Ubuntu 14.04,如果我安装 clang++-6.0clang++-5.0 而不更新 g++(默认为 4.9 版),我最终会出现编译错误。

clang 6 without g++ clang 6 with g++

这与未安装 libc++clang 默认情况下未安装 c++ 库并诉诸使用系统中的内容有关 - 与 g++-4.9 捆绑在一起的那个?

2。我的代码需要 GNU 扩展吗?

显然,如果我指定-std=c++17,它将失败并显示g++-8。但是,g++-7g++-6 会成功。

g++-8 with extensions succeeds VS without extensions fails g++-7 with extensions succeeds VS without extensions succeeds g++-6 with extensions succeeds VS without extensions succeeds

由于我在 clang 构建中安装 g++-8,它们也失败了。我的猜测是,如果我使用g++-7,他们就会成功。 Build details with -std=c++17


非常感谢任何最佳实践建议。这是我在travis-ciclang 中使用clang 的少数第一次尝试。

【问题讨论】:

【参考方案1】:

1。 clang++ 需要安装g++

不——但将使用系统中可用的任何标准库。

在这种情况下,这是因为它是旧的库版本。安装libstdc++-8-dev 解决了这个问题。

2。我的代码需要 GNU 扩展吗?

是的。正如@jonathan-wakely 向我解释的here

分配器的值类型与容器的值类型不同(这正是错误告诉你的内容!)

GCC 将接受它作为-std=gnu++17 模式下的扩展,但您使用-std=c++17 编译会禁用非标准扩展。

不应该在gcc-6gcc-7-std=c++17中也标记为错误吗?

没有,因为静态断言只添加在gcc 8中。

标准方式是using HashMap = std::unordered_map&lt;K, V, KH, KEq, Alloc&lt;std::pair&lt;const K, V&gt;&gt;&gt;;

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86977 std::unordered_map with boost::interprocess allocator in shared memory - drawbacks?

(感谢 @jonathan-wakely 处理我的愚蠢问题!)

【讨论】:

以上是关于g++、clang++、使用libboost的编译花絮——g++7成功时g++8编译失败;的主要内容,如果未能解决你的问题,请参考以下文章

自动模板参数:g ++ 7.3 vs clang ++ 6.0:哪个编译器正确?

g++5 中 std::unordered_set 编译错误的不完整类型,在 clang++ 中编译

GCC/G++/Clang基本用法

如何在 Qt creator 中更改/配置所需的编译器?即在 MSVC/Mingw 或 g++/clang++ 之间切换

溢出的原因(G++ vs Clang++)[关闭]

使用 clang-cl 用 openmp 编译 C 代码