今天,我发现了一个相当有趣的事情g++或者nm......构造函数定义似乎在库中有两个条目.
我有一个标题thing.hpp:
class Thing
{
Thing();
Thing(int x);
void foo();
};
Run Code Online (Sandbox Code Playgroud)
而且thing.cpp:
#include "thing.hpp"
Thing::Thing()
{ }
Thing::Thing(int x)
{ }
void Thing::foo()
{ }
Run Code Online (Sandbox Code Playgroud)
我编译它:
g++ thing.cpp -c -o libthing.a
Run Code Online (Sandbox Code Playgroud)
然后,我继续nm:
%> nm -gC libthing.a
0000000000000030 T Thing::foo()
0000000000000022 T Thing::Thing(int)
000000000000000a T Thing::Thing()
0000000000000014 T Thing::Thing(int)
0000000000000000 T Thing::Thing()
U __gxx_personality_v0
Run Code Online (Sandbox Code Playgroud)
如您所见,两个构造函数Thing都在生成的静态库中列出了两个条目.我的g++是4.4.3,但是同样的行为发生在clang,所以这不仅仅是一个gcc问题.
这不会引起任何明显的问题,但我想知道:
编辑:对于卡尔,没有C参数的输出:
%> …Run Code Online (Sandbox Code Playgroud) 我一直在阅读Clang源代码,发现了一些关于ARM C++ ABI的有趣内容,我似乎无法理解其中的理由.从ARM ABI文档的在线版本:
这个ABI要求C1和C2构造函数返回它(而不是void函数),这样C3构造函数可以尾调用C1构造函数,C1构造函数可以尾调用C2.
(对于非虚拟析构函数也是如此)
我不知道是什么C1,C2以及C3在这里引用.这一节,就是要的§3.1.5从通用(即安腾)ABI的修改,而这部分(至少在这个网上verison)简单地说:
构造函数返回void结果.
无论如何,我真的无法弄清楚这是什么目的:如何使构造函数返回此允许尾部调用优化,以及在什么情况下?
到目前为止,我可以说,构造函数可以尾部调用另一个具有相同this返回值的唯一时间是具有单个基类的派生类,一个简单的构造函数体,没有具有非平凡构造函数的成员,并且没有虚拟表指针.实际上,使用void返回来优化尾部调用似乎实际上更容易,而不是更难,因为这样可以消除单个基类的限制(在多基类的情况下,this指针从最后调用的构造函数不会是this派生对象的指针).
我在这里错过了什么?ARM调用约定是否有this必要使返回成为必要?