gcc 4.4与gcc> 4.4中的默认链接模型

ger*_*wam 5 c++ namespaces g++ linkage

我正在尝试使用两个大型复杂的线性代数库来定义许多相同的函数.我无法重写(在一个案例中合法,但在技术上都在两者中).让我们称它们为"特殊"和"正常",因为我只调用特殊的几个函数.为了始终如一地调用函数中定义的函数,normal.h并且仅在某些情况下调用函数special.h,我做了类似的事情:

namespace special_space
{
#include "special.h"  // Defines foo()
}

#include "normal.h"   // Defines foo()

int main() {
  foo();                // Calls foo() defined in normal.h
  special_space::foo(); // Calls foo() defined in special.h
}
Run Code Online (Sandbox Code Playgroud)

使用g ++ - 4.4,这是我开发它的默认设置,代码编译和链接没有警告,它按照我的预期和我想要的方式执行.这似乎在各种平台,各种Linux,Unix和BSD环境中是一致的.但!如果我使用g ++> 4.4进行编译,我会收到有关多个foo()定义的警告:

在文件special.h :: line:col:warning中:使用C语言链接声明'void special_space :: foo()'[默认启用]

生成的可执行文件然后在调用时段错误special_space::foo().我想/ extern "C++"在special.h中找到的定义中指定可能会解决这个问题,但是我不允许更改special.h.所以我该怎么做?进一步来说:

1)使用g ++ - 4.4是否安全?如果是这样 - 后续版本有什么变化,为什么?

2)如果指定C++链接模型真的会解决这个问题,有没有办法告诉ld默认使用它?

3)如果这两者都没有 - 是否有另一种方法从定义同名函数的库中调用函数?

ros*_*031 1

因此,正如我在评论中发布的那样,将标题包含为

#ifdef __cplusplus
extern "C" {
#endif

#include normal.h

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

对两个标头都执行此操作。

基本上,由于您从 c++ 链接 c 库,这确实进行了名称修改(这就是允许重载的原因),因此您对 c lib 中符号的调用会被链接器破坏。告诉#ifdef __cplusplus链接器不要破坏那些特定函数符号的名称。

理想情况下,库的创建者应该将其包含在其标头中,但您提到您对此无法控制。我对一些生成的代码也有类似的问题。我必须将生成的代码的所有标头包含在其中,以允许 C++ 调用它。

我不知道的是,如果没有这个,它是如何工作的。我肯定必须这样做才能回到 gcc < 4.4。