Hi, thanks for the detailed answers.

So I am very much for keeping init. I just want that if the user specifies a default constructor, it is being called after the value has been initialized to init.

On Wednesday, October 10, 2012 21:11:29 foobar wrote:
Arrays - without changing existing syntax we can use these
semantics:

auto a = new int[](5); // compiler calls T() for each instance
int[12] b; // ditto

And what on earth does that buy you over init? That's what init _does_. And since the value needs to be known at compile time (otherwise arrays won't work for directly initializing _anything_ that needs to be initialized at compile time), a constructor really doesn't buy you anything here at all. init provides a nice, consistent way of initializing or assigning a value to a variable as well as providing a consistent default state for a type when you need to be able to set a variable of that type to a consistent, safe state (e.g. with std.algorithm.move). And as built-in types don't _have_ constructors, there's no other way for generic code to generically initialize
anything.

"What does this buy you over init?" This would help with structs that can't be initialized to a valid value at compile time.
So what I expect to happen in a line like
S[12] s;
Is that they all get blitted to init, followed by a loop that calls the default constructor on each of these. If there is no default constructor, they stay at init and the loop doesn't happen.
This would work with user defined types and with built-in types.
If a constructor throws an exception, then the array is correctly initialized up to the element before the throwing one. The remaining elements are at init.

For member variables I expect this to happen:
If one of your member variables has a default constructor but you do not, then the compiler will generate an empty default constructor for you. This gives your object the same behavior in arrays as described above, which means that the member variable will always be correctly initialized using both init and the deafult constructor. If one of your member variables has a default constructor, and so do you, then the member variable's default constructor is called before your default constructor. If an exception is thrown, the containing object remains at the state it is in (most likely init) If you do not want the default constructor of your member variable to be called, you can declare it as S s = S.init;

For emplace I expect that the default constructor gets called.

For std.algorithm.move you'd have to define which state the source object is in after moving. Since it's a destructive move, I'd expect the object to be at init, as if a destructor had been called. You could implement that with a tiny change to the current implementation. (memcpy from init instead of a statically allocated instance)

This should cover all the cases that you mentioned. It is highly performant (in fact this is very close to the behavior in C++, but faster because it uses init) and it won't affect structs that can be initialized at compile time. It will only be used for cases where you need to do things at runtime, and the users have the full ability to shoot themselves in the foot if they want to.

Reply via email to