C++ allows you to have a member with an incomplete data type (such as char[]) at the end of a struct.
No. C++ does not allow flexible array members. However, C does and some C++ compilers support it as a language extension.
According to the standard, your program is ill-formed.
I would expect fooPtr->bar to either be 'e'
There is no reason to expect that. bar
is an array, and so it will decay into a pointer when used in a value context. When a character pointer is inserted into a stream, the operator will read the characters until null character is reached. Since there is no null character after e
, the output will continue past it.
or throw some kind of read access violation error.
Access violations are undefined behaviour. You can hope for, but not expect an error.
Why does it perfectly print the string up to the null termination character?
This is how the flexible arrays work in C. You allocate a memory buffer for the object; The initial segment is used for other members, and the rest are part of the flexible array member.
Note that the example program is not correct even if we assume support for flexible array members due to aliasing violation. This would be correct, if you were to insist on using the extension:
auto& str = "hello";
auto fooPtr = (foo*)std::malloc(sizeof str);
std::memcpy(fooPtr, str, sizeof str);
std::cout << fooPtr->bar;