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

时间:2015-07-08 16:05:59

标签: 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
}

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

  

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

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

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

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

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

1 个答案:

答案 0 :(得分:1)

因此,当我发表评论时,将标题包含在

#ifdef __cplusplus
extern "C" {
#endif

#include normal.h

#ifdef __cplusplus
}
#endif

使用两个标题执行此操作。

基本上,既然你要链接来自c ++的c库,它确实名称为mangling(这是允许重载的),你对c lib中符号的调用就被链接器破坏了。 #ifdef __cplusplus告诉链接器不要破坏那些特定功能符号的名称。

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

我不知道的是,如果没有这个,它是如何运作的。我肯定不得不这样做回到gcc< 4.4。