Playing around with placement new for arrays, I came up (by chance/mistake) with the following code:
#include <new>
struct X{};
int main()
{
char buf[256];
std::size_t n = 10;
X* p = new (buf) (X[n]); // incorrect way, parenthesis by mistake
//X* p = new (buf) X[n]; // correct way
}
The third line in main
is incorrect, although it compiles. There shouldn't be any parenthesis. clang++ spits out
warning: when type is in parentheses, array cannot have dynamic size
while gcc6 outputs
warning: ISO C++ forbids variable length array [-Wvla] X* p = new (buf) (X[n]);
warning: non-constant array new length must be specified without parentheses around the type-id [-Wvla] X* p = new (buf) (X[n]);
then crashes with an internal compiler error (ICE) in tree_to_uhwi, at tree.h:4044. The internal compiler error appears only in gcc >= 6.
My question: how exactly is the line marked "incorrect" parsed/interpreted, why is it "wrong" to have those parentheses?*
*For the ICE, I'll fill out a bug anyway.
EDIT 1 I just realized that the ICE/warning(s) have nothing to do with user defined types, so the same behaviour is observed for int
instead of struct X
.
EDIT 2 gcc6 bug filled here. The ICE does not appear in gcc5 or earlier versions (only the warnings appear, which are correct).
With the parentheses, the type to be newed comes from a type-id, in this case X[n]
. This is a variable length array which is not standard behavior. Without the parentheses, the type to be newed is a new-type-id, an array of X
.