【问题标题】:Is it safe to link to a static library built with different compiler flags链接到使用不同编译器标志构建的静态库是否安全
【发布时间】:2012-10-03 17:55:29
【问题描述】:

我使用 GoogleTest 测试我的 C++ 项目,在发现 Ubuntu 包中不再分发预编译库后,我在项目网站上发现以下内容:

如果您使用不同的编译器编译 Google Test 和您的测试代码 标志,他们可能会看到相同的不同定义 类/函数/变量(例如,由于在 Google 测试中使用了#if)。 因此,为了您的理智,我们建议您避免安装 预编译的谷歌测试库。相反,每个项目都应该 编译谷歌测试本身,这样它就可以确定相同的 标志用于 Google 测试和测试。

我从中得到的是,将 GoogleTest 与正在测试的项目分开编译是个坏主意。我不明白这是否只是 GoogleTest 的事情,或者这是否是链接库的一般事情。

问题

是否存在链接到预编译的第三方库、编译器标志或其他不安全的情况,如果没有,GoogleTest 有什么特别之处?

【问题讨论】:

  • 您的报价似乎缺少重要部分:If you compile Google Test and your test code using different compiler flags, they may see different definitions of the same class/function/variable (e.g. due to the use of #if in Google Test).
  • 我已经用你指出的那一点更新了报价。

标签: c++ static-libraries googletest


【解决方案1】:

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

来自GCC i386 and x86-64 flags

-malign-double
-mno-align-double

控制 GCC 是在两个字边界还是一个字边界上对齐 double、long double 和 long long 变量。在两个字的边界上对齐双变量会产生在奔腾上运行得更快的代码,但会消耗更多的内存。

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

警告:如果您使用 -malign-double 开关,包含上述类型的结构的对齐方式与已发布的 386 应用程序二进制接口规范不同,并且 与未使用该开关编译的代码中的结构不兼容。

例如,在 32 位系统上使用该标志将使 double 和 long long 与 64 位对齐。如果编译一个没有标志的库,然后在使用标志的同时尝试使用该库,则包含上述类型的结构可能具有不同的对齐方式,并且可能无法互操作。

其他(更简单的)情况也可以确保使用相同的 #define 集以确保使用相同的函数/结构/类定义(以及其他此类 ODR 违规)。例如,在 gcc 中使用“--std=c++11”,它启用了标准库类的 C++ 11 版本,在某些情况下与以前的版本不同。

【讨论】:

  • s/will/may/g -- 取决于运气,图书馆实际上可能工作得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多