why are foos like vector<T>::size no duplicate symbols for linker?
I have a question concerning the code the compiler
generates for template functions.
- why does linker not complain about ctor being there 2-times?
- does linker "strip away" compiler generated template functions (if
necessary)?
- in MSVC map file: does "i" mean: internally created by compiler?
0002:00000990 ?f_a@@YAXXZ 00411990 f a.obj
0002:000009c0 ??0?$ARRAY@H@@QAE@H@Z 004119c0 f i a.obj
0002:00000a10 ?f_b@@YAXXZ 00411a10 f b.obj
// a.cpp
#include "h.hpp"
void f_a() {
ARRAY<int> ia(3);
//...
}
// b.cpp
#include "h.hpp"
void f_b() {
ARRAY<int> ia(5);
//...
}
ARRAY is a minimalistic clone of std::vector. In a.cpp
and b.cpp I use the template class - and thus its (only)
function.
Each .obj file has a definition of ARRAY<int>::ARRAY<int>
as can be seen from assembly files (see below).
Why does linker not complain about duplicate symbols as
e.g. when I define "my_foo" both in a.cpp and b.cpp?
b.obj : error LNK2005: "void __cdecl my_foo(void)" (?my_foo@@YAXXZ)
already defined in a.obj
In the map file I recognize only
0002:000009c0 ??0?$ARRAY@H@@QAE@H@Z 004119c0 f i a.obj
that is version from b.obj is stripped away?
; in a.asm
??0?$ARRAY@H@@QAE@H@Z PROC NEAR ; ARRAY<int>::ARRAY<int>, COMDAT
; _this$ = ecx
; 15 : ARRAY<T>::ARRAY(int size) {
push ebp
mov ebp, esp
; ...
mov esp, ebp
pop ebp
ret 4
??0?$ARRAY@H@@QAE@H@Z ENDP ; ARRAY<int>::ARRAY<int>
; in b.asm
??0?$ARRAY@H@@QAE@H@Z PROC NEAR ; ARRAY<int>::ARRAY<int>, COMDAT
; _this$ = ecx
; 15 : ARRAY<T>::ARRAY(int size) {
push ebp
mov ebp, esp
; ...
mov esp, ebp
pop ebp
ret 4
??0?$ARRAY@H@@QAE@H@Z ENDP ; ARRAY<int>::ARRAY<int>
#ifndef H_HPP
#define H_HPP
template<class T>
class ARRAY {
public:
ARRAY(int size);
// further member foos
private:
T* data_;
};
template<class T>
ARRAY<T>::ARRAY(int size) {
data_ = new T[size];
}
#endif // H_HPP