At the first glance Decorated C++ Names are ideal, they encode all possible C++ method names and allow links between .obj and .lib files. Read Format of a C++ Decorated Name.
But sometime these names can bring some mystics into your life. Today we spent plenty of time revealing a method of a one class doesn't work. It IS called, but you NEVER hit it. This became possible because there were TWO(!!) different classes of the same name.
Here is a prototype project reproducing such a case.
ClassB.obj:
First of all download VS project here: Download
And here are main pieces of code to take a look at:
UserA.cpp:
But sometime these names can bring some mystics into your life. Today we spent plenty of time revealing a method of a one class doesn't work. It IS called, but you NEVER hit it. This became possible because there were TWO(!!) different classes of the same name.
Here is a prototype project reproducing such a case.
ClassA.h:
#include "Base.h"
class ClassA : public Base
class ClassA : public Base
{
public:
ClassA(void);
int f(void);
};
ClassB.h:
#include "Base.h"
class ClassA : public Base
class ClassA : public Base
{
public:
ClassA(int a);
int g(void);
};
The reason why compiler and linker produce no errors is because they have different Decorated C++ Names.
ClassA.obj:
?g@ClassA@@QAEHXZ
(public: int __thiscall ClassA::g(void))
??0ClassA@@QAE@H@Z (public: __thiscall ClassA::ClassA(int))
??1ClassA@@QAE@XZ (public:
__thiscall ClassA::~ClassA(void))
?f@ClassA@@QAEHXZ
(public: int __thiscall ClassA::f(void))
??0ClassA@@QAE@XZ (public: __thiscall ClassA::ClassA(void))
??1ClassA@@QAE@XZ (public:
__thiscall ClassA::~ClassA(void))
Decorated Name of destructors are the same, but linker was surprisingly silent.
(See Viewing Decorated Names for reference)
First of all download VS project here: Download
And here are main pieces of code to take a look at:
UserA.cpp:
#include "StdAfx.h"UserB.cpp:
#include "UserA.h"
#include "ClassA.h"
void UserA::Do()
{
ClassA a;
}
#include "StdAfx.h"ClassAlreadyDefined.cpp:
#include "UserB.h"
#include "ClassB.h"
void UserB::Do()
{
ClassA b(1);
}
#include "stdafx.h"
#include "UserA.h"
#include "UserB.h"
int _tmain(int argc, _TCHAR* argv[])
{
UserA a;
UserB b;
a.Do();
b.Do();
return 0;
}
No comments:
Post a Comment