Home > other >  Template class compiles with C 17 but not with C 20 if unused function can't be compiled
Template class compiles with C 17 but not with C 20 if unused function can't be compiled

Time:05-26

The following compiles without error in VS2019 (version 16.11.15) with C 17 selected as the language. But it fails with C 20 with error "error C2027: use of undefined type 'Anon'"

template <typename T> class a_template
{
public:
    void do_something(class Anon& anon) const;
};

template <typename T> void a_template<T>::do_something(class Anon& anon) const
{
    anon.do_something();
}

The Anon class is of course undefined but the ::do_something function is unused so does not need to be instantiated. This is OK in C 17 but apparently not in C 20.

Is this a change in language rules? If so, can it be fixed without actually defining Anon?

CodePudding user response:

Is this a change in language rules?

No, this is due to the fact that a C compiler is permitted (but not required!) to diagnose errors at the time the template is parsed when all of the instantiations of the template would produce that error.

This means that for your given example, at the time of parsing the definition compilers may or may not issue an error. That is, the compiler can produce an error when parsing the template or may wait until the first template instantiation. Refer to Demo where msvc doesn't issue an error but gcc and clang does.

Perhaps a simpler example would make it more clear :

void func()
{

}

template<typename T> void bar() 
{
     func(3);//compilers are allowed(but not required) to issue error at the time of pasrsing this
}

In the above example, func is a non-dependent name and at the point where we have called func using func(3), the only visible func is the one that accepts 0 arguments and not one. And as i said earlier, some compiler may issue an error(at the time of parsing) even though we've not instantiated bar but some compilers may not. This is because they are allowed to but not required to do so. See demo where msvc doesn't issue an error here but gcc and clang does.


The same logic applies to your example as well. Meaning as Anon is an incomplete type and you have anon.do_something(), some compiler might choose to produce an error even though you have not instantiated a_template and some other compiler might not.

  • Related