VS 2008 irritating copy constructor link dependency

Posted by Paul Hollingsworth on Stack Overflow See other posts from Stack Overflow or by Paul Hollingsworth
Published on 2010-04-07T10:28:34Z Indexed on 2010/04/07 10:33 UTC
Read the original article Hit count: 398

Hi guys, I've run into the following annoying and seemingly incorrect behaviour in the Visual Studio 2008 C++ compiler:

Suppose I have a class library - Car.lib - that uses a "Car" class, with a header called "Car.h":

class Car
{
public:
    void Drive()
    {
        Accelerate();
    }

    void Accelerate();
};

What I'm actually trying to do is use the Car headers (for some other functions), but without having to link with Car.lib itself (the actual class is not called "Car" but I am sanitising this example).

If I #include "Car.h" in the .cpp file used to build a managed C++ .dll, but never refer to Car, everything compiles and links fine. This is because I never instantiate a Car object.

However, the following:

namespace {
class Car
{
public:
    Car(const Car& rhs)
    {
        Accelerate();
    }

    void Accelerate();
};
}

leaves me with the link error:

Error   2   error LNK2001: unresolved external symbol "public: void __thiscall `anonymous     namespace'::Car::Accelerate(void)" (?Accelerate@Car@?A0xce3bb5ed@@$$FQAEXXZ)  CREObjectWrapper.obj    CREObjectBuilderWrapper

Note I've declared the whole thing inside an anonymous namespace so there's no way that the Car functions could be exported from the .DLL in any case.

Declaring the copy constructor out-of-line makes no difference. i.e. the following also fails to link:

class Car
{
public:
    Car(const Car& rhs);
    void Accelerate();
};

Car::Car(const Car& rhs)
{
    Accelerate();
}

It's something specifically to do with the copy constructor note, because the following, for example, does link:

class Car
{
public:
    Car()
    {
        Accelerate();
    }
    void Accelerate();
};

I am not a C++ standards guru but this doesn't seem correct to me. Surely the compiler still should not have had to even generate any code that calls the Car copy constructor.

Can anyone confirm if this behaviour is correct? It's been a while since I used C++ - but I don't think this used to be an issue with Visual Studio 6.0 for example.

Can anyone suggest a workaround that allows one to "re-use" the Accelerate method from within the copy constructor and still have the copy constructor declared inline?

© Stack Overflow or respective owner

Related posts about c++

Related posts about visual-studio-2008