Visual C++ name mangling Archive du 06/07/2019 le 30/10/2019
Calling conventions Archive du 15/08/2019 le 30/10/2019
Microsoft C++ Name Mangling Scheme Archive du 20/07/2006 le 30/10/2019
External functions with the
__declspec(dllimport)
attribute have prefix__imp_
in all compilers except Borland.
C++ Name Mangling/Demangling Archive du 30/04/2002 le 30/10/2019
Le corps d'une méthode template
doit être identique quelque soit le fichier objet généré. Les méthodes template
étant compilés dans chaque fichier objet (possibilité de nombreux doublons), le compilateur va leur donner l'attribut weak
.
Si l'implémentation n'est toujours identique, le compilateur va en prendre une au hasard et la généraliser.
#pragma once #include <iostream> class Entete { public: static void go() { #ifdef HACK std::cout << "A" << std::endl; #else std::cout << "B" << std::endl; #endif } };
#pragma once class A { public: static void go(); };
#pragma once class B { public: static void go(); };
#define HACK #include "ClasseA.h" #include "Entete.h" void A::go() { Entete::go(); }
#undef HACK #include "ClasseB.h" #include "Entete.h" void B::go() { Entete::go(); }
#include "ClasseA.h" #include "ClasseB.h" int main() { A::go(); B::go(); }
U __cxa_atexit U __dso_handle U _GLOBAL_OFFSET_TABLE_ 000000000000005d t _GLOBAL__sub_I__ZN1A2goEv 0000000000000010 t __static_initialization_and_destruction_0(int, int) 0000000000000000 T A::go() 0000000000000000 W Entete::go() U std::ostream::operator<<(std::ostream& (*)(std::ostream&)) U std::ios_base::Init::Init() U std::ios_base::Init::~Init() U std::cout U std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) 0000000000000000 r std::piecewise_construct 0000000000000000 b std::__ioinit U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
U __cxa_atexit U __dso_handle U _GLOBAL_OFFSET_TABLE_ 000000000000005d t _GLOBAL__sub_I__ZN1B2goEv 0000000000000010 t __static_initialization_and_destruction_0(int, int) 0000000000000000 T B::go() 0000000000000000 W Entete::go() U std::ostream::operator<<(std::ostream& (*)(std::ostream&)) U std::ios_base::Init::Init() U std::ios_base::Init::~Init() U std::cout U std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) 0000000000000000 r std::piecewise_construct 0000000000000000 b std::__ioinit U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
On voit que le symbole Entete::go()
est défini deux fois avec l'attribut weak. Mais le #define
étant différent, les deux implémentations sont différentes.