The following program compiles without warnings in GCC and Clang and produces the expected output:
#include <initializer_list>
#include <iostream>
constexpr std::initializer_list<std::initializer_list<const char*>> list = {
{"a", "b", "c"},
{"d"}
};
int main() {
for (const auto& outer: list) {
std::cout << "level:\n";
for (const auto& inner: outer) {
std::cout << " " << inner << "\n";
}
}
}
Using MSVC however, the program does not produce any output at all.
Is this program valid according to the C++ standard? Is this a bug in MSVC? If this is not valid C++ then why is there no warning from GCC or Clang? Is there a better way to create a constexpr nested list where the inner list does not have a fixed size?
[dcl.init.list]/6(from C++20 draft N4860) states thatThey include these examples:
The standard continues, in the same paragraph, with
(emphasis mine)
In your example, I believe, it is equivalent to example
i3; thus the use of the initializer is valid. However, theconstexpr, I think, is what is causing the issue. If you removeconstexpr, MSVC, g++, and clang are all happy and execute the code.I might be wrong, but I'd actually think this is a bug in MSVC. When running the code, MSVC exits with
STATUS_ACCESS_VIOLATION. I'm assuming this is because the addresses are no longer valid that it's trying to reference when printing -- usingintinstead ofconst char*consistently printed0for me, though I'd expect that to be more random like access uninitialized memory.