为啥成员函数的符号很弱?

Posted

技术标签:

【中文标题】为啥成员函数的符号很弱?【英文标题】:Why is the symbol of member function weak?为什么成员函数的符号很弱? 【发布时间】:2021-03-02 15:35:54 【问题描述】:

我使用g++ (7.3.0) 编译了这段 C++ 代码。

struct C 
  __attribute__((noinline)) int foo()  return 0; ;
;

int bar(C &c)  return c.foo(); 

使用nm 我发现foo 很弱。这是由于 C++ 规范还是 GCC 的决定?

实验流程:

$ g++ test.cpp -c -Og  
$ nm test.o  
0000000000000000 T _Z3barR1C  
0000000000000000 W _ZN1C3fooEv

【问题讨论】:

能否发布您用于编译文件的命令行并发布nm 的输出? o found that bar is weakfoo弱,不是bar @KamilCuk,对不起,我把它们弄混了。 afaik weak 不是标准规定的;这是一个实现细节。 【参考方案1】:

那是 C++ 规范还是 GCC 的决定?

两者兼而有之。并不是说 C++ 规范处理强符号或弱符号(它不处理)。但它确实会影响 GCC 的行为,因为通常扩展会尝试建立在标准强制行为之上。

当您在类主体中定义成员函数时,它会自动成为内联函数。在 C++ 语言中,内联函数是可以有多个定义的函数,只要它们出现在不同的翻译单元中。这不是问题,因为在 C++ 中,内联函数必须在每个翻译单元中具有完全相同的定义(直至标记序列)。因此,尽管它们是“不同”的定义,但它们是相同的,因此可以在某个时候简化为一个。

函数实际上不必在调用站点内联。就 C++ 而言,inline 是关于单一定义规则和链接的。这样你就有了,根据规范,C::foo 可以有多个定义。

然后你指定__attribute__((noinline)),所以函数不能被物理内联,所以每个TU都必须包含函数的符号。

这只剩下一个选择。符号一定要弱,否则不同翻译单元中的不同符号会互相干扰。通过使符号变弱,您可以进行强制定义并避免物理内联函数,同时维护 C++ 规范。这些不同的符号代表完全相同的功能,因此任何一个都可以在链接时“获胜”。

【讨论】:

以上是关于为啥成员函数的符号很弱?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我可以在成员函数中使用尚未声明的成员变量?

未定义符号,使用指针 C++ 访问成员函数

为啥 PRIVATE 成员函数不能成为另一个类的友元函数?

为啥线程过程应该是静态或成员函数

为啥可以删除任何函数,但只能删除默认的特殊成员函数? [复制]

为啥 const 函数可以使用静态成员对象的非常量函数?