|
From: vl106 on 27 Jun 2008 16:28 { Please confine responses to standard C++ and generic concepts of compilation and linking, i.e. not going overboard in environment-specific discussion. -mod } 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 -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: vl106 on 28 Jun 2008 07:16 "vl106" <vl106(a)hotmail.com> schrieb im Newsbeitrag news:e60a9665-c7ef-49f4-8d31-087379969737(a)56g2000hsm.googlegroups.com... >{ Please confine responses to standard C++ and generic concepts of >compilation > and linking, i.e. not going overboard in environment-specific > discussion. -mod } > > 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? Okay. I learnt that the standard requires a compiler/linker not to cause an error. That is new to me. For the chapters I read so far only dealt with the language itself. I didn't know that it also imposes requirements on the build environments. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alberto Ganesh Barbati on 28 Jun 2008 07:58 vl106 ha scritto: > > I have a question concerning the code the compiler > generates for template functions. > > - why does linker not complain about ctor being there 2-times? Because the standard requires this to occur. > - does linker "strip away" compiler generated template functions (if > necessary)? Probably. > - 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 This isn't a C++ question. Wrong place to ask this. > > 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 You are seeing it in the wrong way. From the C++ standard point of view, a "compiler" can be naively seen as a complex process that produce the final executable, given the source files. The most common implementations, for example those deriving from the C approach, split the process in three steps: pre-processing, compilation, linking. As these three steps are usually performed by different programs, it's customary to call those programs pre-processor, compiler and linker, but that's a distortion and the source of major confusion, because it narrows the term "compiler" to one particular step, but "compiler" *is* the whole process! There are no separate concepts as "compiler" and "linker" in the C++ standard! The C++ standard provides the required semantic that a compiler is expected to implement. One required behaviour is that ODR (the One Definition Rule) is not violated. In the case of the two definitions of the regular function my_foo() you are violating the ODR, the program is ill-formed and you have to get a diagnostic. In the case of a function generated by a template instantiation, you are *not* violating the ODR as there is still only one *definition* of the template. You may have multiple points of instantiation for the same template but you still have just *one* specialization of the template (see 14.6.4.1). Now that is what the standard requires in abstract. How it's achieved in practice, as I said, it's not relevant for standard point of view. One possible way of implementing this, and the one you are actually seeing, is that one specialization is actually produced in every translation unit and then all but one of the instantiations are discarded in a subsequent "link" step. This is not the only possibility. For example I know there are compilers that maintain a template instantiations database separate from the translated output of each translation unit (aka ".obj" files). HTH, Ganesh -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: basic c++ inquiry Next: why are foos like vector<T>::size no duplicate symbols for linker? |