编译花絮 g++, clang++, 使用 libboost -- g++8 编译失败时 g++7 成功;

Compilation tidbits on g++, clang++, using libboost -- g++8 compilation fails when g++7 succeeds;

本文关键字:编译 失败 g++7 成功 g++8 libboost g++ clang++ 使用      更新时间:2023-10-16

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

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

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

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

该代码是我当前闭源库中的精简版本,灵感来自问题 std::unordered_map 中的答案,共享内存中的 boost::进程间分配器 - 缺点?作者:塞赫

#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_segment{ipc::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 worldn");
return 0;
}

问题

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

使用 Ubuntu 14.04,如果我在不更新g++的情况下安装clang++-6.0clang++-5.0,我最终会遇到编译错误。

  • 没有 G++ 的 clang 6
  • 使用 G++ 的 Clang 6

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

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

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

  • 带扩展的 g++-8 成功 VS 没有扩展失败
  • 带扩展的 g++-7 成功 VS 没有扩展
  • 成功
  • 带扩展的 g++-6 成功 VS 没有扩展
  • 成功

由于我在 clang 版本中安装了g++-8,因此它们也会失败。我的猜测是,如果我使用g++-7,他们就会成功。使用-std=c++17构建详细信息


任何最佳实践建议都非常感谢。这是我为数不多的第一次尝试在travis-ci中使用clang,或者一般clang

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

否 -- 但将使用系统中可用的任何标准库。

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

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

是的。正如@jonathan-wakely在这里向我解释的那样

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

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

它不应该也被标记为gcc-6中的错误并与-std=c++17gcc-7吗?

否,因为静态断言仅在gcc 8中添加。

标准方法是using HashMap = std::unordered_map<K, V, KH, KEq, Alloc<std::pair<const K, V>>>;

  • https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86977
  • 标准::unordered_map 与 boost::共享内存中的进程间分配器 - 缺点?

(感谢@jonathan-wakely处理我的菜鸟问题!