Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

constexpr difference between gcc v10 and v9: bug or feature

If compiled with gcc v10 the code below exibits an error but for gcc v9 the code is ok.

template<auto N>
struct A {
    constexpr auto size() const {
        return N;
    }  
};

template<typename T>
void foo1(const T& a) {
    constexpr auto s = a.size(); // Why error here?
}
template<typename T>
void foo2(T a) {
    constexpr auto s = a.size(); // OK
}
int main() {
    A<10> x1;
    foo1(x1);
    foo2(x1);
    A<x1.size()> x2; // OK
    constexpr auto s = x1.size(); // OK
}

In my understanding the memberfunction size() could be called constexpr in all cases. But there is one case where the behaviour of gcc10 changed compared to gcc9: if the argument is passed by const-ref. I don't understand why this should not be constexpr?

Another example:

template<auto N>
struct A {
    constexpr auto size() const {
        return N;
    }  
};

template<typename T>
constexpr void foo1(const T& a) {
    constexpr auto s = a.size(); // Why error here?
    return s;
}
template<typename T>
constexpr auto foo2(const T& a) {
    return a.size(); // Why OK here
}
int main() {
    A<10> x1;
    constexpr auto s1 = foo1(x1);
    constexpr auto s2 = foo2(x1);
}

I don't understand the difference.

like image 801
wimalopaan Avatar asked Feb 20 '20 08:02

wimalopaan


1 Answers

This is GCC bug 66477. It mentions that GCC wrongly accepts reference-type parameters in constant expressions.

This bug is fixed for GCC 10.


The reason why a.size() is not allowed in constant expressions is mentioned in this post.

like image 77
xskxzr Avatar answered Nov 01 '22 14:11

xskxzr