开发者

C++/VS2005: Defining the same class name in two different .cpp files

Somewhat of an academic question, but I ran into this while writing some unit tests.

My unit test framework (UnitTest++) allows you to create structs to serve as fixtures. Usually these are cu开发者_运维百科stomized to the tests in the file, so I put them at the top of my unit test file.

//Tests1.cpp

struct MyFixture {  MyFixture() { ... do some setup things ...} };

TEST_FIXTURE(MyFixture, SomeTest)
{
  ...
} 

//Tests2.cpp

struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}};

 TEST_FIXTURE(MyFixture, SomeOtherTest)
 {
  ...
 }

However, I found recently (with VS2005 at least) that when you name the fixture struct using the same name (so now two versions of the struct exist with the same name), then one of the versions is silently thrown out. This is pretty surprising, because I have my compiler set to /W4 (highest warning level) and no warning comes out. I guess this is a name clash, and why namespaces were invented, but do I really need to wrap each of my unit test fixtures in a separate namespace? I just want to make sure I'm not missing something more fundamental.

Is there a better way to fix this - should this be happening? Shouldn't I be seeing a duplicate symbols error or something?


Try sticking the classes in an anonymous namespace, you may find it less distasteful than having to create and name a new namespace for each file.

Don't have access to VS2005 and Cpp unit but this may work..

//Tests1.cpp
namespace
{
struct MyFixture {  MyFixture() { ... do some setup things ...} };
}

TEST_FIXTURE(MyFixture, SomeTest)
{
  ...
} 


//Tests2.cpp
namespace
{
struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}};
}

TEST_FIXTURE(MyFixture, SomeOtherTest)
{
 ...
}


The compiler only works on a single compilation unit at a time; this would be the source file and anything it #includes. Since your classes are in different files, no conflict there.

The linker puts everything together, but it doesn't know about class definitions so it doesn't see a conflict either.

Back in the days of C, it was quite common for the linker to recognize that you had two different functions with the same name and generate an error message. With inline functions and templates in C++, it can't do that anymore - different compilation units will often contain duplicates of the same function, so the linker just assumes they're the same.


This is basically a consequence of the fact that classes need to be defined in header files, which leads to having redundant definitions of the class in each object file. So a linker that can handle C++ linkage has to fold redundant class declarations together and pretend that the class was declared only once.

There isn't any way for the linker to distinguish between a single class included into multiple objects and multiple classes with the same name in multiple objects.

You have to use namespaces (or a better language), to get around this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜