使用 clang 5.0.1/6.0.0 编译成功,使用 5.0.2/6.0.1 编译失败

Posted

技术标签:

【中文标题】使用 clang 5.0.1/6.0.0 编译成功,使用 5.0.2/6.0.1 编译失败【英文标题】:Compilation successful with clang 5.0.1/6.0.0, fails with 5.0.2/6.0.1 【发布时间】:2018-08-14 14:33:21 【问题描述】:

TL;DR:Clang 6.0.0 编译我的程序; 6.0.1 没有。回归?还是由于测试不完整?代码错误?

我最近在我正在构建的库中集成了 Boost Interprocess。使用 GCC 效果很好,但使用 Clang 得到的结果好坏参半。

+---------------------------+-----------+-------------------+-------------------+
|          System           | GCC 6/7/8 | Clang 6.0.0/5.0.1 | Clang 6.0.1/5.0.2 |
+---------------------------+-----------+-------------------+-------------------+
| Ubuntu 14.04 (Travis)     | Succeeds  | Not available     | Fails (see below) |
| Linux Mint 19 (my laptop) | Succeeds  | Succeeds          | (?)               |
+---------------------------+-----------+-------------------+-------------------+

在包含 Boost Interprocess 之前,使用 clang 编译会导致一些与 GNU 扩展相关的警告...

warning: token pasting of ',' and __VA_ARGS__ is a GNU extension
      [-Wgnu-zero-variadic-macro-arguments]
  L->debug(LFMT fmt, __FILENAME__, __LINE__, __FUNCTION__, ##__VA_ARGS__);

...和宏扩展:

warning: extension used [-Wlanguage-extension-token]
  SET_WRAPPED(pthread_rwlock_init, pthread_handle);
  ^
/home/joaomlneto/Documents/GitHub/fpthreads/fpthreads/src/fpthread/util/wrap.cpp:14:16: note: expanded from macro 'SET_WRAPPED'
    WRAP(x) = (typeof(WRAP(x))) dlsym(handle, #x);\

但否则编译成功。

在我开始使用 Boost Interprocess 后,在 shared_memory_segment 中实例化 unordered_map 会导致 clang 5.0.2/6.0.1(travis-ci 上的版本)出现致命错误,但在 5.0.1/ 版本上成功6.0.0(在 linux mint 19 中可用,这是 ubuntu 18.04 的默认设置)。有问题的代码摘录(受https://***.com/a/49738871/4288486 启发)如下:

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, Thread> ThreadMap;
Manager *thread_mgr = _segment.get_segment_manager();
_threads = _segment.find_or_construct<ThreadMap>("threads")(thread_mgr);

Full output from Travis

【问题讨论】:

minimal reproducible example 会有很大帮助。 我会努力的 :-) 这是通过在运行前安装 g++-6 / g++-7 / g++-8 来解决的。没有最新的标准 C++ 库,它使用的是旧 gcc(4.9 版)中的一个,捆绑在 Ubuntu 14.04 中。至少这是我的理解。 【参考方案1】:

clang 正在使用系统中捆绑的 c++ 库(我的理解是它不像g++ 那样捆绑了一个库?)。默认情况下,Ubuntu 14.04 包含g++-4.9libstdc++,这已经过时了(我猜)。

安装例如libstdc++-8-dev 解决了我的问题。

【讨论】:

以上是关于使用 clang 5.0.1/6.0.0 编译成功,使用 5.0.2/6.0.1 编译失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Clang 编译 C++?

mac 使用gcc 为啥编译错误是clang 提示

一文带你梳理Clang编译步骤及命令

在 Android Studio 中使用 ollvm 版本的 clang 编译 so

在Windows使用clang编译器

__m256 未知类型(clang 5.1/i5 CPU)?