August 23, 2012
> How would it be different from defining a default constructor? Structs
> specifically _don't_ have default constructors, because init must be known at
> compile time, and all kinds of restrictions would have to be placed on a
> default constructor (enough to make it pointless) to ensure that it would work
> as an init value that there's really no point to it. The kind of stuff that
> you'd want to do in a default constructor but can't do by directly
> initializing the member variables is precisely the kind of stuff that you
> _can't_ do with a struct, because init must be known at compile time, must
> always generate the same result, couldn't throw exceptions, etc.
>
> So, sure, at times it would be great to have a default constructor for
> structs, but other design decisions in the language (particularly with regards
> to init) simply make that infeasible. It's one of those "forced faults" in
> language design that Andrei likes to talk about.
>
> So, what we get is an init value defined by how the member variables are
> directly initialized and the ability to define a static opCall to get you the
> equivalent of the default constructor in cases where S() is used rather than
> S.init. It's not perfect, but there's not much that we can do about it.
>
> - Jonathan M Davis

My idea was to declare your own .init in a class, not in a struct.


August 23, 2012
On Thursday, August 23, 2012 23:27:18 Namespace wrote:
> My idea was to declare your own .init in a class, not in a struct.

Well, the init for classes will always be null, because class references are
nullable. That's part of the language. Making it so that a class' init value
wasn't guaranteed to be null would definitely complicate both the compiler and
generic code (since it could no longer rely on the fact that a class' init
value was null and would have to do additional checks when it cared). Right
now, you have the guarantee that declaring a class reference allocates
nothing, and changing init so that it could actually initialize the reference
would break that guarantee. That would actually be a serious problem in cases
where you need to be able to declare a class reference but can't initialize it
when declaring it (e.g. a member variable, static variable, or global variable
must be known at compile time if it's directly initialized, which can't be done
with classes, since while you can sometimes use classes in CTFE, they can't
be persisted beyond CTFE).

If you want something that isn't nullable, you'll need a type which which isn't nullable, which means using a struct. I know that you want non-nullable references, but for D2, the best that you're going to get is a struct which wraps a class.

- Jonathan M Davis
August 23, 2012
> If you want something that isn't nullable, you'll need a type which which
> isn't nullable, which means using a struct. I know that you want non-nullable
> references, but for D2, the best that you're going to get is a struct which
> wraps a class.
>
> - Jonathan M Davis

That would be fine if i only have to write:

[code]
void test(NotNullable!Foo f) {
[/code]

and not

[code]
Foo f = new Foo();
NotNullable!Foo nf = f;
test(nf)
[/code]

as well.

This overhead ist the same as if you use precondition. That's the reason why IMO NotNullable as struct isn't a good choice for that situation.

But to overwrite the .init  was just an idea, i didn't think that so much guarantees would be broken. Thanks for your explanation.

August 23, 2012
On Friday, August 24, 2012 01:35:56 Namespace wrote:
> > If you want something that isn't nullable, you'll need a type
> > which which
> > isn't nullable, which means using a struct. I know that you
> > want non-nullable
> > references, but for D2, the best that you're going to get is a
> > struct which
> > wraps a class.
> > 
> > - Jonathan M Davis
> 
> That would be fine if i only have to write:
> 
> [code]
> void test(NotNullable!Foo f) {
> [/code]
> 
> and not
> 
> [code]
> Foo f = new Foo();
> NotNullable!Foo nf = f;
> test(nf)
> [/code]
> 
> as well.

I would expect you to be able to do

test(NotNullable!Foo(new Foo));

and with a helper function, you could have something like

test(notNullable(new Foo));

- Jonathan M Davis
August 24, 2012
> I would expect you to be able to do
>
> test(NotNullable!Foo(new Foo));
>
> and with a helper function, you could have something like
>
> test(notNullable(new Foo));
>
> - Jonathan M Davis

But then you have an lvalue and cannot receive it as "ref NotNullable!Foo". Your struct would be copied with the (default) postblit ctor every time you send it to "test", or am I wrong?
August 24, 2012
On Friday, August 24, 2012 02:00:22 Namespace wrote:
> > I would expect you to be able to do
> > 
> > test(NotNullable!Foo(new Foo));
> > 
> > and with a helper function, you could have something like
> > 
> > test(notNullable(new Foo));
> > 
> > - Jonathan M Davis
> 
> But then you have an lvalue and cannot receive it as "ref NotNullable!Foo". Your struct would be copied with the (default) postblit ctor every time you send it to "test", or am I wrong?

If you passed it a directly constructed NotNullable!Foo or the result of a function, then it wouldn't be copied. It would be moved.

http://stackoverflow.com/questions/6884996/questions-about-postblit-and-move- semantics

And even if it _were_ copied, we're talking about a struct that just holds a class reference, so copying it would be essentially the same as copying the reference. I wouldn't expect NotNullable to even _have_ a postblit constructor, meaning that copying it would use memcpy, which would be very fast. If you have to worry about the efficiency of passing NotNullable!T to a function, then there's something very wrong.

- Jonathan M Davis
August 24, 2012
:D I didn't know that, thanks.
August 24, 2012
On 08/23/2012 12:38 PM, Dmitry Olshansky wrote:
> On 23-Aug-12 23:33, Namespace wrote:
>> But to write your own init property would still be nice, or not?
>
> Either way it has to be CTFEable. Can't you just do:
>
> struct A{
> X field = generateX();
> }
>
> and thus set .init to whatever you want.
> Otherwise it will inevitably rise question of the point of "= x;" syntax
> if initializes are overridden by custom .init.
>

Yes, that works:

struct S
{
    int i = init_i();
    double d = init_d();

    static int init_i()
    {
        return 42;
    }

    static double init_d()
    {
        return 1.5;
    }
}

void main()
{
    assert(S().i == 42);
    assert(S().d == 1.5);
}

So the language doesn't give us the ability to define a CTFE-able default constructor but writing individual "constructors" for each member works.

Ali
August 24, 2012
Am 23.08.2012 19:15, schrieb nocide:
> struct has no default constructor and instances are initialized with the
> init property.
> Can I declare or override the init property for a custom defined struct?
>

Ok, the initializer forks fine for me,
but I've encounterd following situation: (simplified code)

// This compile fine
struct Foo {
    union {
        struct {
            int a = 1, b = 2, c = 3, d = 4;
        }
        float[4] e;
    }
}


// but this doesn't compile
struct Foo {
    union {
        struct {
            int a, b, c, d;
        }
        float[4] e = [ 1.0f, 2.0f, 3.0f, 4.0f ];
    }
}
Foo f;  // Error: struct main.Foo overlapping initialization for struct


Is this a bug?


August 24, 2012
On 08/24/2012 09:39 AM, nocide wrote:
> Am 23.08.2012 19:15, schrieb nocide:
>> struct has no default constructor and instances are initialized with the
>> init property.
>> Can I declare or override the init property for a custom defined struct?
>>
>
> Ok, the initializer forks fine for me,
> but I've encounterd following situation: (simplified code)
>
> // This compile fine
> struct Foo {
>      union {
>          struct {
>              int a = 1, b = 2, c = 3, d = 4;
>          }
>          float[4] e;
>      }
> }
>
>
> // but this doesn't compile
> struct Foo {
>      union {
>          struct {
>              int a, b, c, d;
>          }
>          float[4] e = [ 1.0f, 2.0f, 3.0f, 4.0f ];
>      }
> }
> Foo f;  // Error: struct main.Foo overlapping initialization for struct
>
>
> Is this a bug?
>
>

Yes.
1 2
Next ›   Last »