и там, кажется, есть много уместной информации там.

ня я обнаружил довольно интересную вещь оg++ или жеnm... Определения конструктора имеют две записи в библиотеках.

У меня есть заголовокthing.hpp:

class Thing
{
    Thing();

    Thing(int x);

    void foo();
};

А такжеthing.cpp:

#include "thing.hpp"

Thing::Thing()
{ }

Thing::Thing(int x)
{ }

void Thing::foo()
{ }

Я собираю это с:

g++ thing.cpp -c -o libthing.a

Затем я бегу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

Как видите, оба конструктора дляThing перечислены с двумя записями в сгенерированной статической библиотеке. мойg++ 4.4.3, но такое же поведение происходит вclangтак что это не простоgcc вопрос.

Это не вызывает никаких видимых проблем, но мне было интересно:

Почему определенные конструкторы перечислены дважды?Почему это не вызывает проблем с «множественным определением символа __»?

РЕДАКТИРОВАТЬ: Для Карла выход безC аргумент:

%> nm -g libthing.a
0000000000000030 T _ZN5Thing3fooEv
0000000000000022 T _ZN5ThingC1Ei
000000000000000a T _ZN5ThingC1Ev
0000000000000014 T _ZN5ThingC2Ei
0000000000000000 T _ZN5ThingC2Ev
                 U __gxx_personality_v0

Как видите ... одна и та же функция генерирует несколько символов, что все еще довольно любопытно.

И пока мы на этом, вот раздел сгенерированной сборки:

.globl _ZN5ThingC2Ev
        .type   _ZN5ThingC2Ev, @function
_ZN5ThingC2Ev:
.LFB1:
        .cfi_startproc
        .cfi_personality 0x3,__gxx_personality_v0
        pushq   %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        movq    %rdi, -8(%rbp)
        leave
        ret
        .cfi_endproc
.LFE1:
        .size   _ZN5ThingC2Ev, .-_ZN5ThingC2Ev
        .align 2
.globl _ZN5ThingC1Ev
        .type   _ZN5ThingC1Ev, @function
_ZN5ThingC1Ev:
.LFB2:
        .cfi_startproc
        .cfi_personality 0x3,__gxx_personality_v0
        pushq   %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        movq    %rdi, -8(%rbp)
        leave
        ret
        .cfi_endproc

Таким образом, сгенерированный код ... ну ... то же самое.

РЕДАКТИРОВАТЬ: Чтобы увидеть, какой конструктор действительно вызывается, я изменилThing::foo() к этому:

void Thing::foo()
{
    Thing t;
}

Сгенерированная сборка:

.globl _ZN5Thing3fooEv
        .type   _ZN5Thing3fooEv, @function
_ZN5Thing3fooEv:
.LFB550:
        .cfi_startproc
        .cfi_personality 0x3,__gxx_personality_v0
        pushq   %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        subq    $48, %rsp
        movq    %rdi, -40(%rbp)
        leaq    -32(%rbp), %rax
        movq    %rax, %rdi
        call    _ZN5ThingC1Ev
        leaq    -32(%rbp), %rax
        movq    %rax, %rdi
        call    _ZN5ThingD1Ev
        leave
        ret
        .cfi_endproc

Так что это вызывает полный конструктор объекта.

Ответы на вопрос(1)

Ваш ответ на вопрос