奇怪的链接行为,最新的g ++

时间:2011-04-15 03:31:46

标签: c++ gcc linker g++

我一直在与g ++发生奇怪的链接行为,但是,我只是一名学生,我想知道这是否正常。

我正在尝试将汇编代码(机器:fedora 14 gnome 32bits x86 i686 intel i7)与c ++代码链接,并使汇编代码从c ++文件中实例化的函数调用方法。似乎在类声明中实现一个方法会阻止它被放入链接器表中,除非它在原始源中至少使用过一次。

class A
{
public:
    void showSUP() {
        cout<<"sup";
    }
};

在实习A后,您将无法拨打_ZN1A7showSUPEv,因为它尚未放入链接表中:

call _ZN1A7showSUPEv

但是,如果在声明A的同一.cpp中调用A :: showSUP(),则从单独的汇编文件中调用它将起作用。

A

的实例化
class A
{
    void showSUP();
};

A::showSUP()
{
    cout<<"sup";
}

调用_ZN1A7showSUPEv即可。

我的问题是,为什么第一个例子不起作用。

提前谢谢大家。

3 个答案:

答案 0 :(得分:5)

有一些属性可以用这种方式为函数指定

classe A
{
  public:
    void showSUP(){
      cout<<"sup";
    } __attribute__((used))
};

请参阅gcc attribute overview

  

使用       在版本中找到:3.1-3.4       说明:

     This attribute, attached to a function, means that code must be
     emitted for the function even if it appears that the function is
     not referenced.  This is useful, for example, when the function
     

是            仅在内联汇编中引用。

答案 1 :(得分:2)

  • 对于内联函数编译器 只会输出使用该功能的代码。
  • 定义的功能 里面的类定义是 内联(通常)。
  • 功能不是 使用。
  • 因此:没有功能 二进制。

答案 2 :(得分:2)

通常,如果您希望函数包含在最终的库/可执行文件中,则需要:

  • 使用
  • 非内联

inlined函数是一个函数,其代码只需复制并粘贴到函数使用的位置(由编译器),这样就不会有函数调用。这是一个机会优化,因此在某些地方可能会内联函数而在其他地方不会内联,具体取决于上下文。大多数非常短的函数(所谓的单行)通常都是内联的。

在过去,要内联一个函数需要在当前的翻译单元中定义,即:

  • 要么在标题中定义(就像你的情况一样),因此可以在所有来源中内联,包括此标题
  • 要么在源文件中定义,要么可以在源文件中内联

现在我们也有LTO(链接时间优化),如果激活,链接器实际上可能内联函数调用。这些优化还负责从未使用的符号中清除生成的库/二进制文件。

您的问题有两种可能的解决方案:

  • 在源文件中定义函数,它是标准的,可能不会被删除
  • 使用编译器特定属性将函数标记为已使用,以便它不会被删除

在后一种情况下,如果您希望具有可移植性,我只能建议使用宏(ATTRIBUTE_USED)并根据当前使用的编译器定义其内容。