Question

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 customized 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?

Was it helpful?

Solution

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)
{
 ...
}

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top