Trying to initialize an array created with 'new'

Started by
16 comments, last by DividedByZero 8 years, 5 months ago

The difference is that [3] would cause a compile error if the literal didn't have three members (stops you from making mistakes). In this case it's easy to see that it does visually, but [] is really better for things where you actually don't want to constrain it to a set number of members, like a list of things that you add or remove things to/from occasionally between compiles.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
Advertisement

You can't initialize dynamic arrays that way, apparently (in MSVC 2013 anyway, it appears to work for PODs, but not structs - I'm not sure if that's just undefined behavior, or expected).

If the posted struct definition is the actual, complete definition that is used, it's well-defined, and the compiler must accept it (otherwise it's a bug).

5.3.4/17 states that the new-initializer is interpreted according to the initialization rules of 8.5 for direct initialization. 8.5 in turn explains direct initialization as the initialization that occurs in the forms T x(a); T x{a}; as well as in new expressions. It further states that initialization semantics are that if the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized.

Now, 8.5.4/3 defines list-initialization as aggregate initialization if T is an aggregate.

We are initializing an array of structures. An array is always an aggregate, and this particular struct qualifies as an aggregate, too (no user-declared constructors, no private or protected non-static data members, no base classes, no virtual functions). 8.5.1 explicitly defines "recursive" list-initialization for the case that a list element itself is a list.

Therefore, aggregate initialization has to happen. The array is aggregate-initialized, aggregate-initializing every struct in the array recursively. Each element in the struct is copy-initialized from one value in the list-in-list. (Note that narrowing conversions in aggregate-initialization will make the program ill-formed, so you must make sure to avoid these.)

No constructors were hurt making this post.

Ok. If thats the case one can rule out any errors in type deduction in initializer in this case and accept that the method works for structs as well... otherwise it would have signalled it with an error.

So are you saying he should or should not get garbage values?


If the posted struct definition is the actual, complete definition that is used, it's well-defined, and the compiler must accept it (otherwise it's a bug).

It looks like you're right. In that case, MSVC 2013 definitely has a bug in its c++11 implementation when it comes to initializing dynamic arrays of non-PODs.

 

Ok. If thats the case one can rule out any errors in type deduction in initializer in this case and accept that the method works for structs as well... otherwise it would have signalled it with an error. So are you saying he should or should not get garbage values?

If the code is as-shown (that is, there are no "surprises" that we don't know about, such as Float3 really having something that disqualifies it as being an aggregate), there should certainly be no garbage values. It's properly initialized, so the values must be well-defined.

The difference is that [3] would cause a compile error if the literal didn't have three members (stops you from making mistakes).

It results in a compile error if you have too many, but not if you have too few.


int arrayA[3] = {1, 2, 3};
int arrayB[3] = {1, 2}; //Too few: Compiles fine
int arrayC[3] = {1, 2, 3, 4}; //Too many: Doesn't compile.

in MSVC 2013 anyway, it appears to work for PODs, but not structs
...
MSVC 2013 definitely has a bug in its c++11 implementation when it comes to initializing dynamic arrays of non-PODs.

You might be mistaking fundamental types for PODs. structs can be PODs, and the OP's struct is a POD (at least, what he posted was a POD).

Most times when people say POD they usually are talking about a struct, at least in my limited experience.

The difference is that [3] would cause a compile error if the literal didn't have three members (stops you from making mistakes).


It results in a compile error if you have too many, but not if you have too few.


Wow, that's gross.


It would appear that VS2015 also ignores the braced initializer for array new, and does not indicate a syntax problem. I'm sending a report presently.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

It would appear that VS2015 also ignores the braced initializer for array new, and does not indicate a syntax problem. I'm sending a report presently.



So this would appear to be a bug with VS.net 2015 then?

.NET isn't involved in this. It's a problem with either the C++ compiler implementation or else Microsoft's interpretation of the standard.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

.NET isn't involved in this. It's a problem with either the C++ compiler implementation or else Microsoft's interpretation of the standard.


Yeah, I know that .net is not involved. Just force of habit of writing it that way, due to the way that Microsoft previously named the whole package. smile.png

This topic is closed to new replies.

Advertisement