Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to resolve a gcc specific compilation error

Tags:

Here is a program I am trying to compile.

template <typename T>
struct A
{
    T foo() const
    {
        return 1;
    }
};

template <typename T>
struct B : A<T>
{
    using U = A<T>;
    T foo() const
    {
        return 2;
    }
};

template <typename T>
struct D
{
    B<T> b;
    int foo() const
    {
        // using U = typename B<T>::U; // compilation succeeds if I uncomment this line
        return b.U::foo();
    }
};

int main()
{
    D<int> d;
    return d.foo();
}

I see different behaviour across gcc 9.2, clang 9.0.0 and icc19.0.1. The program fails to compile with gcc giving an error U has not been declared, compiles fine with clang and has a non-trivial assembly with icc. Why is the behaviour different across these compilers?

I tried reading dependent_name but gave up since I couldn't follow it properly. From what little I understand, data member b inside struct D has a dependent type and U should have been resolved when the template is instantiated.

Compiled the above code with the above compilers on godbolt.org here: https://godbolt.org/z/n_Wl44. I used C++17 with -O3 flag. Thanks in advance!!!

like image 309
Empty Space Avatar asked Oct 23 '19 17:10

Empty Space


1 Answers

U in b.U::foo(); should be looked up during instantiation in the context of B<T> first, finding using U = A<T>;, so that b.U::foo() calls foo() defined in A<T>. [basic.lookup.classref]/4

The lookup should be delayed until instantiation and no lookup at definition should happen, because b is dependent as its type depends on the template parameter T. [temp.dep.expr]/5

Therefore this seems to be a bug in GCC. A very similar code example has been posted in this bug report, which demonstrates the same issue as far as I can tell. The bug is currently marked status "new".

As far as I can tell the other failing compilers shown in the godbolt.org conformance view posted by @TedLyngmo are derivatives of GCC, so it is not like independent compilers are disagreeing on this.

like image 189
walnut Avatar answered Dec 03 '22 00:12

walnut