简体   繁体   中英

GCC misses some errors or warnings

Consider this copy constructor of a template class which has an error:

MyClass( MyClass const& other )
  : m_x( other.n_x )  // typo: should be `other.m_x`.
{
  // does something
}

Or this copy assignment operator overload which does not return anything ( return-type warning):

MyClass& operator=( MyClass const& other )
{
   // does something
   // WARNING: with no `return *this`.
}

It has happened several times that GCC compiles the code without any error/warning at first, and later after some changes on other parts of the code, it complains about an issue that it was already there (mostly in constructors or assignment operators as far as I remember).

Does GCC ignores template functions or member function of a template class that are not instantiated throughout the code completely? What is happening under the hood?

I am using GCC 9.3 and GCC 10.1 with -O3 -Wall -Wpedantic -Werror .

UPDATE As @someprogrammerdude suggested, here is a minimal reproducible example:

template< typename T >
class MyClass {
public:
  MyClass( T x ) : m_x( x ) { };
  MyClass( MyClass const& other )
    : m_x( other.n_x )
  {
    std::cout << "in copy constructor" << std::endl;
  }

  MyClass& operator=( MyClass const& other )
  {
    this->m_x = other.m_x;
  }

  T m_x;
};

and here is the sample usage which compiles fine as is. But uncommenting some parts gives an error or warning.

int main()
{
  MyClass< int > c( 2 );
  std::cout << c.m_x << std::endl;

  /* Uncommenting these lines gives an error in constructor.
   * error: ‘const class MyClass<int>’ has no member named ‘n_x’*/
  //MyClass< int > d = c;
  //std::cout << d.m_x << std::endl;

  /* Uncommenting these lines gives a warning in copy assignment operator.
   * error: no return statement in function returning non-void [-Werror=return-type] */
  //MyClass< int > d( 3 );
  //d = c;
  //std::cout << d.m_x << std::endl;
  return 0;
}

It is clearer to me now when I created this example. So, there would be no check at all if it is not instantiated?

GCC checks templates only by static checker unless they were instantiated. Standard doesn't require even that.

This is possible if your template class is derived from other template. It is not known if that template will have a specialization with such member or not.

Eg this code is still valid

template <template <class> class T, class V>
struct A {
    V m_x;
};

template <template <class> class T, class V>
struct B : A <T, V>
{
   V t;
    
   V getY() { return this->m_y; } 
  // the `this->` is needed exactly because `m_y` wasn't declared
    
   B(B& a) : t(a.m_y) {}
};

because it may be followed by and used only with this specialization:

template <class V>
struct A<std::complex, V> {
    V m_x;
    V m_y;
};

In your particular example other.n_x is marking n_x as being dependent on template parameters of MyClass (similar to this-> idiom), so it is possible that n_x would exist at later point. If it won't exist at point of substitution and instantiation, then it would produce compile error, but not before.

Class template members are instantiated on-demand, separately from the class itself. It's how the language works. Template code is compiled when it is instantiated; until then the source is simply parsed , which does not verify semantics, only some basic structure syntax (such as matching brackets, parentheses, etc).

MyClass 's copy constructor will be instantiated the first time an object of that type is copied, or never if it's never copied.

You can ask the compiler to instantiate all template members for a certain type using explicit instantiation syntax:

template class MyClass<int>;  // explicit instantiation

Note: an optimizing linker (such as g++) will eliminate unused code so this won't increase the binary size, only the compilation time will increase slightly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM