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?