这样做[二进制]安全吗?
struct Foo { #if __cplusplus > 199711L Foo( std::initializer_list<int> & list ) { /* ... */ } #endif };
我已经看过这个主题,但是没有回答 OP 原始问题。
有没有更好的方法来实现这种行为?
2 回答
它可能很好,DirectX 结构是通过这种方式实现的,但是它支持 C 和 C++。
我假设你:
将此类代码编译到库中,一直在升级您的编译器,现在想用 C++11 编译您的代码(或者因为您没有代码而不能),或者,
在 C++11 之前的库中已有代码,现在您已经升级了编译器,您希望使用上述代码并与旧库“兼容”,或者,
想要在没有 C++11 的情况下编译代码并将其与使用相同编译器使用 C++11 编译的代码链接。
在每种情况下,答案都不是 C++ 问题,而是编译器 ABI 问题,因为它涉及 (i) 链接阶段是否有效以及 (ii) 类的运行时形式等是否仍然有效在编译器/版本/编译器设置之间有效。
因此,您需要检查您正在使用的编译器的文档,以确定它是否是“二进制安全的”。
注意#1:如果您的编译器已经(/已经)以任何方式更改了异常处理发出的代码设计、类的 RTTI 布局和/或名称修改方案,那么您的答案是,“不,这不安全。” 但这些可能不是唯一的情况。
注意#2:如果它使用相同的编译器和不同的设置(例如,使用 C++11 和不使用),那么当您排除某些模块的代码并将其用于其他模块时,您在技术上违反了 ODR(一个定义规则)假设同一个程序。在这种情况下,结果在技术上是实现定义的,但是,由于它不是虚拟的,因此它非常、非常、非常有可能与大多数编译器一起工作,前提是只使用一个编译器的一个版本。