On Friday, 17 May 2013 at 22:45:01 UTC, Timothee Cour wrote:
Although I agree that having a default constructor would be
convenient, I
think the problem is that S.init should be known at compile
time by the
spec.
Maybe we could support the following syntax, with a static this
instead of
this :
struct S
{
int x=11;
int y = void;
static this() // hypothetical
{
// x would already be initialized to int.init here
assert(x == int.init);
// y is left uninitialized here
y=x*x;
}
}
On Fri, May 17, 2013 at 2:34 PM, Andrej Mitrovic
<andrej.mitrov...@gmail.com
wrote:
On 5/17/13, Walter Bright <wal...@digitalmars.com> wrote:
> I oppose this. D has a lot of nice features because of the
> .init
property.
> Default constructors wreck that.
Would they? I'm thinking the process would be:
struct S
{
int x;
int y = void;
this() // hypothetical
{
// x would already be initialized to int.init here
assert(x == int.init);
// y is left uninitialized here
}
}
Maybe that's already clear. But why is .init actually such a
big
problem? If it becomes arbitrarily expensive to call .init of a
struct, well it's because it has to be - if the user really
provided
an expensive default ctor. But it's entirely the user's
responsibility. So then .init can even throw, but throwing
exceptions
isn't a big deal. Is there some other problem?
A custom default ctor in a struct is one of the most asked for
features. Just yesterday we spent several hours explaining to
a C++
user why a default ctor doesn't work, and what .init is for.
The whole
conversation could have been avoided if D had support for
custom
default ctors for structs. This topic comes up very often in
IRC and
the forums.
May be we can allow default ctor, but ensure that it can be
interpreted at compile time and initialize .init value with
ctored value?
Foo.init = Foo(); //somewhere in deep of compiler
But there is one trouble.
struct Foo
{
int[] arr;
this()//can be interpreted at compile time
{
arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
}
}
semantically, all new instances of Foo must get separate instance
of array.
Foo f1;
Foo f2;
assert(f1.arr.ptr !is f2.arr.ptr); //expects put FAILS
However, if Foo.init initialized by compiler with Foo() and f1
and f2 will be initialized with Foo.init, f1.arr and f2.arr will
be the same value.
We can also restrict creating of any mutable reference instances
in this() constructor:
struct Foo
{
int[] arr;
immutable int[] arr2;
this()//can be interpreted at compile time
{
arr = new int[3]; //NG
arr = [1,2,3]; //NG
arr2 = [1,2,3]; //OK, because arr2 is immutable and all
instances of foo can contains an single array instance
}
}
But this way is so difficult and isn't much profitable.