Why the same code below compiles fine with CLang and doesn't compile with MSVC?
#include <iostream>
const char * NumberToText(int val)
{
return (const char *[]) {
"Zero",
"One",
"Two",
}[val];
}
int main()
{
std::cout << NumberToText(2);
}
Here is the demo.
And MSVC gives the error:
(5): error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
At the same time CLang compiles and executes this just fine.
In the Error C4576 in VS2015 enterprise I see some ideas that this is because this is C language feature and this is ill-formed in C++, but why CLang compiles this, then?
Can I keep the array anonymous and still get the same result in MSVC C++?
The syntax (T){E1, E2, ...}
, where T
is a type and E*
are expressions, is not valid standard C++ syntax.
It is valid C though, where it is a so-called compound literal. Some compilers allow compound literals in C++ code when not compiling in a strict standard-compliance mode (e.g. -pedantic-errors
), but it is not obvious how these compound literals behave in a C++ context.
In particular, in GCC (and probably Clang as well), compound literals have different semantics in C++ code than in C code. Their lifetime and value category are different. See https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html.
So, I suggest not using them, even if you only compile for compilers supporting them.
Your example can be easily rewritten in standard-conforming C++:
return std::array{
"Zero",
"One",
"Two",
}[val];
or pre-C++17:
return std::array<const char*, 3>{
"Zero",
"One",
"Two",
}[val];