This is allowed:
int a[]{1, 2, 3};
But not this:
auto a = new int[]{1, 2, 3};
You have to specify the bou
As Jonathan Wakely already pointed out in the comments, this is in fact a closed issue. The resolution "should be handled in Evolution Work Group" essentially means WG21 thinks it's not a bad idea per se, but at the same time they don't consider it a defect in the current standard. Which makes sense - there's no hint somewhere that is should work, it's just by analogy.
I think it is because the compiler read files in serial method, it never goes back, (that's why you must use forward declarations for example, and not just wait for function to be declared later). I'm not sure it is the official reason but it just make sense to me.
This is my explanation:
The line int Array[]={1,2,3};
can be processed in serial way like this:
start array: put 1 in the 1st place, put 2 in the 2nd, put three in the 3rd, end array, therefore: array size is 3 integers, so move the stack frame by this size.
But the following line: int *p=new int[]{1,2,3};
should have start with memory allocation, in addition to placing elements in the memory and detect the size. How can it done in a serial way?
To allow something like this you must break the seriality principle, and begin the processing from the end and then go back to call the appropriate allocation size.
EDIT:
In response to the 1st comment
I did some test, in the following code:
class A{
public:
A(){
err2 error;
cout<<sizeof(A)<<endl;
}
err1 error;
};
the compiler appear to leave the inline functions to be compiled as though they come after the class.
The evidence is that no matter the order, member errors detected before function errors.
So in the sample class, I'm getting err1 error
before err2 error
, even though the chronological order is the opposite.
Therefore I guess classes are the exceptional, otherwise in-class functions was very limited in usage of the class itself.
EDIT2:
int Array[]={sizeof(Array)};
gives error, the only reason is the size of array is given after the closing of the array. it is more similar to the problem in the question than int Array[]={1,2};
MSalters' answer addresses why this hasn't been changed in recent versions of the standard. Here I will answer the companion question, "where in the C++11 standard is this forbidden?"
new (int[]){1, 2, 3}
First, we need to note that int[]
is an incomplete type.
... an array of unknown size ... is an incompletely-defined object type. -[basic.types] §3.9 ¶5
Finally, we note that the new
operator does not permit the specified type to be incomplete:
This type shall be a complete object type ... -[expr.new] §5.3.4 ¶1
There isn't anything in the standard to make an exception for this case when the braced-init-list syntax is used.
new int[]{1, 2, 3}
int[]
in this case gets parsed using the new-type-id production, which uses the noptr-new-declarator production to parse the square brackets:
noptr-new-declarator:
[ expression ] attribute-specifier-seqopt
noptr-new-declarator [ constant-expression ] attribute-specifier-seqopt
Note that expression is not marked optional, therefore this syntax simply fails to parse.