相关疑难解决方法(0)

构造符号的双重发射

今天,我发现了一个相当有趣的事情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++ gcc constructor

100
推荐指数
1
解决办法
7809
查看次数

为什么析构函数默认不是虚拟的[C++]

为什么C++默认情况下不会为至少有一个其他虚函数的类创建析构函数? 在这种情况下,添加一个虚拟析构函数不需要任何费用,并且没有一个(几乎?)总是一个bug.C++ 0x会解决这个问题吗?

c++ virtual-destructor

26
推荐指数
1
解决办法
3737
查看次数

为什么我的汇编输出中有两个析构函数实现?

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)

c++ assembly name-mangling c++17

20
推荐指数
2
解决办法
2384
查看次数

有没有办法调用纯虚拟类的"删除析构函数"?

我在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一起使用详细指南的回答)在其报告中忽略该符号?

c++ destructor gcov lcov c++11

11
推荐指数
1
解决办法
1348
查看次数

链接.如何同时定义和定义符号?

$ 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)

那么,如何解释这个输出?

  1. 这是符号的多个定义(三个T) - 它可能是怎样的?为什么链接器生成这样的库违反ODR?什么目的?为什么他们都有相同(和奇怪)的地址(0000000000000000)?
  2. 同一个符号如何同时定义(T)和undefined(U)?

c++ linker

6
推荐指数
1
解决办法
644
查看次数