今天,我发现了一个相当有趣的事情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) 为什么C++默认情况下不会为至少有一个其他虚函数的类创建析构函数? 在这种情况下,添加一个虚拟析构函数不需要任何费用,并且没有一个(几乎?)总是一个bug.C++ 0x会解决这个问题吗?
而objdump我的.o文件的显示,我对同一类两种不同的析构函数.为什么?
Disassembly of section .text._ZN1AD0Ev:
0000000000000000 <_ZN1AD0Ev>:
0: 53 push %rbx
1: be 00 00 00 00 mov $0x0,%esi
6: 48 89 fb mov %rdi,%rbx
9: 48 c7 07 00 00 00 00 movq $0x0,(%rdi)
10: ba 2c 00 00 00 mov $0x2c,%edx
15: bf 00 00 00 00 mov $0x0,%edi
1a: e8 00 00 00 00 callq 1f <_ZN1AD0Ev+0x1f>
1f: 48 89 df mov %rbx,%rdi
22: be 08 00 00 00 mov $0x8,%esi
27: 5b pop %rbx …Run Code Online (Sandbox Code Playgroud) 我在Ubuntu Trusty上使用C++ 11和g ++ 4.8.
考虑一下这个片段
class Parent {
public:
virtual ~Parent() = default;
virtual void f() = 0;
};
class Child: public Parent {
public:
void f(){}
};
Run Code Online (Sandbox Code Playgroud)
叫做使用
{
Child o;
o.f();
}
{
Parent * o = new Child;
delete o;
}
{
Child * o = new Child;
delete o;
}
Run Code Online (Sandbox Code Playgroud)
我使用gcov生成我的代码覆盖率报告.它报告带有符号的析构函数_ZN6ParentD0Ev永远不会被调用,而它_ZN6ParentD2Ev是.
回答构造函数符号的双重发射和GNU GCC(g ++):为什么它会生成多个dtors?报告_ZN6ParentD0Ev是删除构造函数.
有没有在Parent课堂上调用这个"删除析构函数"的情况?
附属问题:如果没有,有没有办法获得gcov/lcov代码覆盖工具(使用gcov与CMake/CDash一起使用的详细指南的回答?)在其报告中忽略该符号?
$ nm --demangle /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/libsupc++.a | grep "__cxxabiv1::__class_type_info::~__class_type_info"
Run Code Online (Sandbox Code Playgroud)
给出以下输出:
0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
U __cxxabiv1::__class_type_info::~__class_type_info()
U __cxxabiv1::__class_type_info::~__class_type_info()
Run Code Online (Sandbox Code Playgroud)
那么,如何解释这个输出?
T) - 它可能是怎样的?为什么链接器生成这样的库违反ODR?什么目的?为什么他们都有相同(和奇怪)的地址(0000000000000000)?T)和undefined(U)?c++ ×5
assembly ×1
c++11 ×1
c++17 ×1
constructor ×1
destructor ×1
gcc ×1
gcov ×1
lcov ×1
linker ×1