Friday 12 April 2013


Today I've been looking at a C++ problem, well when I say problem, I think there are no problems you can't work around in C++, but this particular problem relies on someone spotting a compiler error and acting correctly.

The trouble I have is that the compiler error is pretty obscure - this I will admit as a problem with C++ compilers in general - and that the error really has no meaning in the context of the solution I am trying to make the programmer come to.

Let me explain with a little code, I have a class a base class in fact, we'll call this A, and this class has a constant inside, lets say the "Name"... Now we don't want the base class to define a value for this constant we just want it to make all classes which derive from it realise they must define a value for this constant... So the code might look like this;

#include <string>

using namespace std;

class A
{
public:
static const string c_Name;
};

Now, normally here we'd then have:

const string A::c_Name ("DefaultValue");

And if we did nothing untoward would happen at this point, the derived classes could all use c_Name, just it would have only this default value, and the static instance of c_Name in one derived class would NOT be the same string as in another class, they are separate values... so there's no problems.

class B : public A
{
};

Now this derived class has a c_Name, but its "DefaultValue", so you would expect to just define a new instance:

const string B::c_Name ("New Value For Constant");

Unfortunately, this is totally wrong, because the new definition of the constant in B causes a redefinition of the constant in the base class, and multiple initization is not allowed.

So, we remove the default value...

#include <string>

using namespace std;

class A
{
public:
static const string c_Name;
};

//const string A::c_Name ("DefaultValue");

class B : public A
{
};

const string B::c_Name ("New Value For Constant");

And everything now compiles, there's no problem... Except that the base class does not provide a default name, so we're relying on the programmer to spot when they miss the definition of name and not assume they've got to define it in the base class and so stop our intended operation...

But the compiler error is horrible... lets take a look at it from Visual Studio 2010:

"error LNK2001: unresolved external symbol" and then the hell that is the output... 



The error makes sense, we've defined a static in the base class and not defined it anywhere, my problem is how do I educate a programmer - whom will most likely not read my documentation - to NOT define one in the base and so break hundreds of classes in the future - but know to define it in the class they just wrote and give it a meaningful name?

No comments:

Post a Comment