Bug in MSVC when constexpr fails for certain references

Viewed 71

I recently ran across this apparent bug in MSVC.

int a[10];        // zero initialized array in the BSS
int(&b)[10] = a;  // Reference to above array

The following template works fine to get the number of elements in the array but is unable to get the value as a compile time constant in MSVC. It works fine in GCC

template<typename T, std::size_t N>
constexpr std::size_t size(T(&)[N]) {
    return N;
};

Example: https://godbolt.org/z/sr891866f

Full Code:

#include <cstddef>
#include <array>

int a[10];    // zero initialized array in the BSS
int(&b)[10] = a;

template<typename T, std::size_t N>
constexpr std::size_t size(T(&)[N]) {
    return N;
};

int main()
{
    int a1[size(a)]; // Works
    int b1[size(b)]; // Fails: Error C2131: expression did not evaluate to a constant
}

This apparent bug also occurs using the more modern, std::array

#include <array>
const std::array<int, 10> a{};
const std::array<int, 10>& b = a;

int main()
{
    // Interestingly, sizeof, which requires a compile time constant, works on both
    int a1[sizeof(a) / sizeof(int)]{}; // Works
    int b1[sizeof(b) / sizeof(int)]{}; // Works

    int a2[a.size()]{}; // Works
    int b2[b.size()]{}; // Fails: Error C2131: expression did not evaluate to a constant
}

Are these bugs in MSVC?

0 Answers
Related