vsoftco vsoftco - 2 months ago 35
C++ Question

Parenthesis around placement new operator for arrays

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 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).

Answer

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.