如果我正在建立一个图书馆,我假设某些"客户"该库可能只使用C ++ 11,我可以使用C ++ 14为其内部编译库本身吗?与C ++ 11相比,是否存在API / ABI /链接兼容性问题?只要我避免使用公共API中的某些新功能,使用C ++ 14实现和构建库是否安全?如果是这样,我必须避免哪些内容?或者在最终的软件项目中混合使用C ++ 11和C ++ 14本质上是不兼容的?
它是一个跨平台的库,BTW,所以我需要在Linux,OSX和Windows上构建它。
答案 0 :(得分:9)
如果我正在构建一个库,我假设该库的某些“客户”可能只使用C ++ 11,那么我可以使用C ++ 14为其内部编译库本身吗?
是的,总的来说应该是可能的。
我正是为GCC实现的Filesystem TS而做的。 <experimental/filesystem>
标头用纯C ++ 11编写,可以包含在C ++ 11客户端中,但libstdc++fs.a
中的实现是用C ++ 14编写的。
与C ++ 11相比,是否存在API / ABI /链接兼容性问题?
C ++ 11和C ++ 14之间没有任何变化,需要实现来破坏它们的链接时间兼容性。这并不意味着实现不会打破它,但它们不是必需的。
对于GCC,我相信C ++ 11和C ++ 14完全兼容API和ABI,除了下面提到的constexpr
和大小 - 释放问题。
使用C ++ 14实现和构建库是否安全,只要我避免使用公共API中的某些新功能,如果是这样,我必须避免哪些内容?
这取决于你的编译器,但理论上它是可能的。
显然避免在C ++ 11中无效的任何C ++ 14语言特性(例如函数返回类型推导,或具有auto
参数的通用lambda,或变量模板)和任何C ++ 14个库实体,如std::make_unique
,std::integer_sequence, or
std :: shared_timed_mutex`。
可以在SD-6中找到C ++ 14中几乎所有更改的列表。
需要注意的一点是,在C ++ 11和C ++ 14之间,非静态constexpr
成员函数的含义发生了变化。在C ++ 11中,这个成员函数是const
:
struct X {
constexpr int foo();
};
在C ++ 14中,它是非常量的。要与C ++ 11和C ++ 14兼容,您应明确将其限定为const
:
struct X {
constexpr int foo() const;
};
这在C ++ 11和C ++ 14中都是一样的。
另一个需要注意的是,在C ++ 11和C ++ 14中,这个运算符意味着不同的东西:
void operator delete(void*, std::size_t);
如果C ++ 11客户端代码定义了该函数,那么用C ++ 14 编译的库可以最终调用它而不是通常的operator delete(void*)
,这可能是错误的事情。这可能非常罕见,并且在实际代码中不是问题,但它是可能的。 G ++和Clang允许您使用-fno-sized-deallocation
编译C ++ 14代码以禁用新功能,这样您的C ++ 14库代码就永远不会调用operator delete
的那个版本。