链接到使用不同编译器标志构建的静态库是否安全?

11
我使用GoogleTest来测试我的C++项目,但在发现Ubuntu软件包中不再分发预编译库后,我在项目网站上找到了以下信息:
如果您使用不同的编译器标志编译Google Test和测试代码,则它们可能会看到相同类/函数/变量的不同定义(例如由于在Google Test中使用#if)。因此,为了您的健康,我们建议避免安装预编译的Google Test库。相反,每个项目都应该编译Google Test本身,以便可以确保对Google Test和测试使用相同的标志。
我理解的是,单独编译GoogleTest而不是与被测试项目一起编译是一个坏主意。但我不明白的是,这是否仅适用于GoogleTest,还是适用于链接库的常规情况。
问题: 是否存在任何情况下连接到预编译的第三方库是不安全的,无论是编译器标志还是其他情况?如果没有,那么GoogleTest有什么特殊之处?

1
你的报价似乎缺少重要部分:“如果您使用不同的编译器标志编译Google Test和测试代码,则可能会看到相同类/函数/变量的不同定义(例如,由于在Google Test中使用#if)。 ” - Jesse Good
我已经根据你指出的部分更新了报价。 - user360907
1个回答

6

有一些编译器标志,特别是与对齐相关的标志,可能会导致问题。

来自GCC i386和x86-64标志

-malign-double
-mno-align-double

控制GCC是否将double、long double和long long变量对齐在两个字的边界或一个字的边界上。将double变量对齐到两个字的边界上可以产生在Pentium上运行得更快的代码,但代价是更多的内存。

在x86-64上,默认启用-malign-double选项。

警告:如果使用-malign-double开关,则包含上述类型的结构以不同于386的发布应用程序二进制接口规范对齐,并且与不使用该开关编译的代码中的结构不兼容。
例如,在32位系统上使用该标志将使doubles和long longs对齐为64位。如果您在没有该标志的情况下编译库,然后在使用该标志时尝试使用库,则包含上述类型的结构可能具有不同的对齐方式,并且可能无法互操作。
其他(更简单的)情况也可以确保相同的#define集以确保使用相同的函数/结构/类定义(以及其他ODR违规)。例如,在gcc中使用“--std=c++11”可以启用C++ 11版本的标准库类,这些类在某些情况下与先前版本不同。

1
根据运气,这个库也许会正常工作。将“will”替换为“may”。 - Fred Foo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接