Undefined reference link error for virtual conversion operator

Viewed 53

Following is a minimal example code producing the link error: (all in the same file)

class A is only declared

class A{
public:
       A();
      ~A();
};

class B has A as member

class B{
public:
        B(){};
        ~B(){};
        A a;
};

following class is to be used as a template base class

template<class T>
class base{
public:
       base(){};
       ~base(){};
       virtual operator T() = 0;
};
class child : public base<B>{
public:
       child(){};
       ~child(){};
       operator B()
       {
         B o;
         return o;
       }
};

main:

int main(){
  child obj;
  return 0;
}

On compiling the code, I get the following link error:

in function `B::B()':
undefined reference to `A::A()'
undefined reference to `A::~A()'
error: ld returned 1 exit status

My question is, if the conversion operator is not being called in the code, why the link error? Also what can be a workaround, I would still like the operator to be virtual but don't have A's definition.

1 Answers

My question is, if the conversion operator is not being called in the code, why the link error?

Because it is still compiled, hence linked, making the One Definition Rule come into play.

It is true that a C++ compiler is allowed to optimize away and remove the definition of the operator since it's not being called. However the C++ standard does not require that. Your C++ compiler still compiles it, and this results in an ODR violation and a link failure.

There is no guaranteed workaround, and no exceptions to the One Definition Rule. You'll have to look into your compiler's documentation to see if it offers any optimization options that might work, but as far as C++ is concerned, the ODR rules the roost.

Related