为什么每个成员函数都有自己的.text。*部分?

问题描述 投票:1回答:1

我知道发生名称修改的情况。我不明白的是:

class MyClass{
public:
  int doStuff(int a){
    return a+1;
  }
};

int main(){
  MyClass myclass;
  myclass.doStuff(2);

  return 0;
}
 > g++ -c  -O0 blah.cpp && objdump -h blah.o 

blah.o:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .group        00000008  0000000000000000  0000000000000000  00000040  2**2
                  CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD
  1 .text         00000043  0000000000000000  0000000000000000  00000048  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  2 .data         00000000  0000000000000000  0000000000000000  0000008b  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  3 .bss          00000000  0000000000000000  0000000000000000  0000008b  2**0
                  ALLOC
  4 .text._ZN7MyClass7doStuffEi 00000013  0000000000000000  0000000000000000  0000008c  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  5 .comment      00000036  0000000000000000  0000000000000000  0000009f  2**0
                  CONTENTS, READONLY
  6 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000d5  2**0
                  CONTENTS, READONLY
  7 .eh_frame     00000058  0000000000000000  0000000000000000  000000d8  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

为什么MyClass.doStuff在其自己的部分中,部分名称是该成员函数的错误符号?

我认为这对于链接工作不是必需的,因为它是链接时匹配的符号,而不是节。即。如果所有内容都在.text中,则它应该可以工作。

有没有办法使这种情况不发生?

c++ gcc g++
1个回答
2
投票

不是完全重复,但请参阅我对this related question的答复以了解更多详细信息。

g++(或clang++)编译a的内联定义类成员函数,例如int MyClass::doStuff(int)作为弱全局符号的内联定义,例如_ZN7MyClass7doStuffEi 1在目标文件中,只要翻译单元引用该函数,并将此定义放在其自己的功能部分。

之所以这样做是因为:-

每个翻译中必须存在一个内联函数定义引用功能的单位。但是可能有链接中包含相同对象的多个目标文件_ZN7MyClass7doStuffEi的定义。

因此_ZN7MyClass7doStuffEi必须是弱势且全局的。 所以链接器可以自由选择任何一个定义并丢弃其余的,按One Definition Rule的要求。Global,因此无论是相同定义之一从其他对象文件中引用为链接can选择的对象在确实引用它的链接中。

最后将_ZN7MyClass7doStuffEi的每个定义放在每个目标文件中都有自己的功能部分,以确保链接器can放弃此函数定义。如果其他程序引用的全局符号可以在相同的位置定义_ZN7MyClass7doStuffEi部分,则可能无法舍弃一个定义,而导致多定义错误。


[1]您的评论“测试代码中的成员函数不是外部的”是不正确的。您不能也不能声明成员函数extern,但是(弱或强)全局符号具有外部链接。
© www.soinside.com 2019 - 2024. All rights reserved.