mardi 3 septembre 2019

Constexpr member function on l-value ref object: Clang and gcc disagree

When a class has a constexpr member function and that member function is being evaluated on an l-value object in a constexpr context, clang and gcc disagree whether the result is a constexpr value. Why? What is the best workaround making both compilers compile?

When the object is passed by value, both compilers succeed compiling.

Clang versions trunk, 8, 7: static_assert expression is not an integral constant expression

and

Gcc versions trunk, 8.1, 7.4: compiles with no error

#include <array>

using A = std::array<int, 10>;

void foo(const A& a){
    // clang: static_assert expression is not an integral constant expression
    static_assert(a.size() > 0, "");
}


void foo2(A a){
    // this compiles on both clang and gcc
    static_assert(a.size() > 0, "");
}

// Some custom code with the same symptom:
class B{
  public:
    constexpr int size()const{
        return 42;
    }
};

void foo3(const B& b){
    // clang: static_assert expression is not an integral constant expression
    static_assert(b.size() > 0, "");
}


void foo4(B b){
    // this compiles on both clang and gcc
    static_assert(b.size() > 0, "");
}

https://godbolt.org/z/9vmyli

Current workaround:

void foo5(const B& b){
    static_assert(B().size() > 0, "");
}

Aucun commentaire:

Enregistrer un commentaire