编译花絮 g++, clang++, 使用 libboost -- g++8 编译失败时 g++7 成功;
Compilation tidbits on g++, clang++, using libboost -- g++8 compilation fails when g++7 succeeds;
我在 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.0
或clang++-5.0
,我最终会遇到编译错误。
- 没有 G++ 的 clang 6
- 使用 G++ 的 Clang 6
这与没有安装libc++
和clang
默认情况下不安装c ++库以及诉诸于使用系统中的内容有关 - 与g++-4.9
捆绑在一起的那个?
2. 我的代码需要 GNU 扩展吗?
显然,如果我指定-std=c++17
,它将失败并g++-8
.但是,它将通过g++-7
和g++-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++17
gcc-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处理我的菜鸟问题!
- 包含模板文件的递归会导致编译失败
- 提升 1.64 单元测试编译失败
- C++模板的模板编译失败
- 使用已删除的函数进行编译失败,并显示 uclibc
- MinGW-w64 编译失败,nullptr_t
- 使用提升线程时编译失败
- 编译花絮 g++, clang++, 使用 libboost -- g++8 编译失败时 g++7 成功;
- CMake + Qt,moc 编译失败,无法实现 QMetaObject 方法(编译器找不到基本 ui 对象的标头?
- 带有引用的std::tuple在clang中编译失败,但在gcc中编译失败
- 解决由于在哈希函数中使用了不完整的类型而导致的编译失败
- 将XCode升级到verison 11.1后,C++编译失败
- 添加类型名会导致程序编译失败
- 将 qi::lexeme 添加到灵气中的规则时编译失败
- 如果我在下面的代码中使用 list 而不是 vector,为什么在我尝试在迭代器之间执行减法的行中编译失败?
- 返回 std::stringstream - 编译失败
- 编译失败:strlen 不是 std 的成员
- MSBuidel - 将资源文件添加到项目后静态库编译失败
- C++ - 在 std::thread 中调用重载函数时编译失败
- QtWebEngine 到嵌入式 Linux 交叉编译失败
- 使用 glibc 2.7 包含路径编译失败