++ , , .
,
. , , ,
. - .
++ ++,
, ++: ,
. ,
,
. , GCC ++
GNU linker .
, , ++- -
-
, -
, -
. .
,
, ,
,
, .
, , :
, ODR ,
- ,
"" . , , .
:
thing.hpp
#ifndef THING_HPP
#define THING_HPP
#ifndef ID
#error ID undefined
#endif
template<typename T>
struct thing
{
T id() const {
return T{ID};
}
};
#endif
ID - , .
:
foo.cpp
#define ID 0xf00
#include "thing.hpp"
unsigned foo()
{
thing<unsigned> t;
return t.id();
}
foo, thing<unsigned>
t, t.id().
, thing<unsigned>, foo,
: -
:
boo.cpp
#define ID 0xb00
#include "thing.hpp"
unsigned boo()
{
thing<unsigned> t;
return t.id();
}
foo.cpp, , boo foo
ID= 0xb00.
, , :
main.cpp
#include <iostream>
extern unsigned foo();
extern unsigned boo();
int main()
{
std::cout << std::hex
<< '\n' << foo()
<< '\n' << boo()
<< std::endl;
return 0;
}
, hex, foo() -
= f00 - boo() - = b00.
foo.cpp, -save-temps,
:
g++ -c -save-temps foo.cpp
foo.s,
thing<unsigned int>::id() const (mangled = _ZNK5thingIjE2idEv):
.section .text._ZNK5thingIjE2idEv,"axG",@progbits,_ZNK5thingIjE2idEv,comdat
.align 2
.weak _ZNK5thingIjE2idEv
.type _ZNK5thingIjE2idEv, @function
_ZNK5thingIjE2idEv:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movl $3840, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
:
.section .text._ZNK5thingIjE2idEv,"axG",@progbits,_ZNK5thingIjE2idEv,comdat
.text._ZNK5thingIjE2idEv, , ,
.text ( ) , .
, , .text.<function_name>, .
, <function_name>.
:
.weak _ZNK5thingIjE2idEv
. thing<unsigned int>::id() const weak.
GNU .
. ,
. ,
. ( ) ,
. ,
.
:
.type _ZNK5thingIjE2idEv, @function
thing<unsigned int>::id() - .
_ZNK5thingIjE2idEv,
.LFB2. 3840 (= 0xf00).
boo.cpp :
g++ -c -save-temps boo.cpp
, thing<unsigned int>::id() boo.s
.section .text._ZNK5thingIjE2idEv,"axG",@progbits,_ZNK5thingIjE2idEv,comdat
.align 2
.weak _ZNK5thingIjE2idEv
.type _ZNK5thingIjE2idEv, @function
_ZNK5thingIjE2idEv:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movl $2816, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
, : 2816 (= 0xb00).
, , , :
( ), . ,
: -
, thing<T>
T = unsigned. , thing<unsigned> ,
_ZNK5thingIjE2idEv a.k.a thing<unsigned int>::id() const.
, , thing<unsigned>
. thing<unsigned>
-,
, -,
.
, .
.
g++ -c main.cpp
, _ZNK5thingIjE2idEv,
:
g++ -o prog main.o foo.o boo.o -Wl,--trace-symbol='_ZNK5thingIjE2idEv',-M=prog.map
foo.o: definition of _ZNK5thingIjE2idEv
boo.o: reference to _ZNK5thingIjE2idEv
, , _ZNK5thingIjE2idEv
foo.o boo.o.
, :
./prog
f00
f00
foo() boo() thing<unsigned>().id()
foo.cpp.
thing<unsigned int>::id() const
boo.o? :
prog.map
...
Discarded input sections
...
...
.text._ZNK5thingIjE2idEv
0x0000000000000000 0xf boo.o
...
...
boo.o,
.
prog , foo.o boo.o
:
$ g++ -o prog main.o boo.o foo.o -Wl,--trace-symbol='_ZNK5thingIjE2idEv',-M=prog.map
boo.o: definition of _ZNK5thingIjE2idEv
foo.o: reference to _ZNK5thingIjE2idEv
_ZNK5thingIjE2idEv boo.o
foo.o. , :
$ ./prog
b00
b00
:
...
Discarded input sections
...
...
.text._ZNK5thingIjE2idEv
0x0000000000000000 0xf foo.o
...
...
.text._ZNK5thingIjE2idEv
foo.o.
.
.
,
,
. ,
- , -
, -
. ,
.
,
, .
, ,
, , , .
, ODR ,
, . #include - ( ) - .