Search code examples
c++visual-c++c++20constexprcompiler-bug

Why does MSVC say a call to a virtual constexpr functional call operator does not result in a constant expression?


I have a class that wraps an array. It inherits from an abstract base class defining one virtual constexpr method for the function-call operator. In the child class, I override said method and access the internal array:

#include <cstddef>
#include <array>
#include <initializer_list>

template <typename T, std::size_t N>
class ContainerBase {
public:
    virtual constexpr const T& operator()(std::size_t i) const = 0;
};

template <typename T, std::size_t N>
class Container : public ContainerBase<T, N> {
public:
    constexpr Container(std::initializer_list<T> data) {
        std::copy(data.begin(), data.end(), _items.begin());
    }
    constexpr const T& operator()(std::size_t i) const override {
        return _items[i];
    }
private:
    std::array<T, N> _items;
};

int main () {
    constexpr Container<int, 3> C = {2, -91, 7};
    constexpr int F = C(1);

    static_assert(F == -91);
}

Here is the godbolt link.

To the best of my understanding, this is all legal code in C++20, which allows virtual constexpr. G++ 10.3 and Clang 12 both accept this as valid code, however MSVC 19.33 does not accept it, claiming that variable F is not a constant expression:

msvc_buggy_constexpr.cpp(29,21): error C2131: expression did not evaluate to a constant
msvc_buggy_constexpr.cpp(21,16): message : a non-constant (sub-)expression was encountered
msvc_buggy_constexpr.cpp(31,5): error C2131: expression did not evaluate to a constant
msvc_buggy_constexpr.cpp(21,16): message : a non-constant (sub-)expression was encountered

What gives? This looks like a compiler bug in MSVC to me. I would investigate further but MSVC on godbolt.org seems to be down right now.

I should add, the issue only presents itself when the function call operator method is virtual —when it is not, the issue does not occur.

Can anyone advise?


Solution

  • User @Barry agrees with me that it's definitely a bug in MSVC.

    I've submitted this bug report.

    Hopefully the issue gets resolved soon.

    Thanks all for your comments and further insights, it's very helpful!