Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suppressing "Base class ‘class X’ should be explicitly initialized in the copy constructor" from library header for template class

I am having a problem similar to this one.

I am using a third party library. It defines classes as here (faked all the names due to licensing issues), in file headers/things.h:

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


template < class T, class U >
class B : virtual public A {
public:
    B(T) {}

    B(const B< T,U >) {}

    virtual ~B() {}
};


template < class T, class U >
class  C : virtual public B< T, U > {
public:
    C(T t) : B < T, U > (t) {}

    C(const C< T,U > &other) : B< T,U >(other) {}

    ~C() {}
};

Additionaly, still in the library header:

typedef C< int, int > CC;

The error message is:

cc1plus: warnings being treated as errors
../headers/things.h: In copy constructor ‘C<T, U>::C(const C<T, U>&) [with T = int, U = int]’:
things.cpp:5:   instantiated from here
../headers/things.h:22: warning: base class ‘class A’ should be explicitly initialized in the copy constructor
../headers/things.h: In copy constructor ‘B<T, U>::B(const B<T, U>&) [with T = int, U = int]’:
../headers/things.h:23:   instantiated from ‘C<T, U>::C(const C<T, U>&) [with T = int, U = int]’
things.cpp:5:   instantiated from here
../headers/things.h:12: warning: base class ‘class A’ should be explicitly initialized in the copy constructor

In things.cpp, I have:

#include "things.h"

CC make_cc() {
    CC cc(123);
    return cc;
}

int main() {
    CC cc = make_cc();
    return 0;
}

File layout is:

../
|-- source
|   `-- things.cpp
`-- headers
    `-- things.h

I am aware of what this warning means and I am not asking for that. Since it is in a third party library, I am very reluctant to modify (fix) it for maintenence reasons. I simply want to ignore this warning.

I am compiling my code with:

g++ things.cpp -o things -Wall -Wextra -Werror -isystem ../headers/

I am using -isystem for specifying the directory, because the gcc docs state that:

All warnings, other than those generated by ‘#warning’ (see Diagnostics), are suppressed while GCC is processing a system header. (...) The -isystem command line option adds its argument to the list of directories to search for headers, just like -I. Any headers found in that directory will be considered system headers.

This seems to work in general, as nearly all warnings from the third party library are indeed suppressed.

Unfortunately, as this declaration happens to be an instantiation of a typedef'd templated class, the compiler thinks that it is my code that it is compiling, not the (fake) system header.

As said in the referenced question, it is impossible to suppress this warning only, and I'd have to disable -Wextra instead, which I don't want to do.

Question: Is it possible to suppress this warning anyhow? To make gcc aware it's not my code, but the library code?

I am using gcc 4.1.2.

like image 816
rubikonx9 Avatar asked Feb 05 '15 14:02

rubikonx9


1 Answers

As others have mentioned, using a newer compiler seems to be a better approach than the following, but as you're hands seem to be tied, consider the following approach:

Create wrapper classes around the third party library classes along the lines of

class MyCC {
    CC cc;
};

template<typename T, typename U>
class MyB {
    B<T, U> b;
};

Forward any relevant function calls to make the wrappers as transparent as you feel is necessary. Alternatively you could use something like BOOST_STRONG_TYPEDEF.

The header(s) where these wrappers are defined could then have at the top of the a file:

#pragma GCC system_header

Hopefully that pragma will suppress the warning in the only client that uses the library directly, whereas all other code could then use the wrappers instead, thus not needing the pragma.

like image 112
Matthias Vegh Avatar answered Nov 15 '22 20:11

Matthias Vegh