digitalmars.D.learn - struct init property
- nocide (3/3) Aug 23 2012 struct has no default constructor and instances are initialized with the...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (38/41) Aug 23 2012 You can define the initial values of each member:
- nocide (3/3) Aug 23 2012 [snip]
- nocide (10/13) Aug 23 2012 I've just realized, that I just have to declare default initializer for
- Jonathan M Davis (12/15) Aug 23 2012 The init property is defined by what you directly initialize the struct'...
- Namespace (10/10) Aug 23 2012 It would be great if you could declare your own .init as you can
- Dmitry Olshansky (5/15) Aug 23 2012 Read on :
- Namespace (1/1) Aug 23 2012 But to write your own init property would still be nice, or not?
- Dmitry Olshansky (10/11) Aug 23 2012 Either way it has to be CTFEable. Can't you just do:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (24/33) Aug 23 2012 Yes, that works:
- Jonathan M Davis (19/20) Aug 23 2012 How would it be different from defining a default constructor? Structs
- Namespace (1/34) Aug 23 2012 My idea was to declare your own .init in a class, not in a struct.
- Jonathan M Davis (19/20) Aug 23 2012 Well, the init for classes will always be null, because class references...
- Namespace (16/24) Aug 23 2012 That would be fine if i only have to write:
- Jonathan M Davis (6/31) Aug 23 2012 I would expect you to be able to do
- Namespace (3/8) Aug 23 2012 But then you have an lvalue and cannot receive it as "ref
- Jonathan M Davis (12/25) Aug 23 2012 If you passed it a directly constructed NotNullable!Foo or the result of...
- Namespace (1/1) Aug 23 2012 :D I didn't know that, thanks.
- nocide (23/26) Aug 24 2012 Ok, the initializer forks fine for me,
- Timon Gehr (2/29) Aug 24 2012 Yes.
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?
Aug 23 2012
On 08/23/2012 10:15 AM, nocide wrote: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?You can define the initial values of each member: struct S { int i = 42; double d = 1.5; } void main() { assert(S.init == S(42, 1.5)); } That changes the .init value. You can also define a static opCall() to mimic the default constructor. Note that this method does not affect the .init value: struct S { int i; double d; static S opCall() { S s; s.i = 42; s.d = 1.5; return s; } } void main() { assert(S().i == 42); assert(S().d == 1.5); assert(S.init.i == int.init); import std.math; assert(isnan(S.init.d)); } Note that the static opCall() disables calling automatic destructor (i.e. the S(1, 2) does not work anymore). I am not sure whether that is one of the many struct-related issues at the moment. Ali
Aug 23 2012
[snip] Ah thanks! You just were a little bit faster :)
Aug 23 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?I've just realized, that I just have to declare default initializer for the members. This also works with unions! struct Foo { int a; union { int b = 7; float c; } }
Aug 23 2012
On Thursday, August 23, 2012 19:15:16 nocide wrote: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?The init property is defined by what you directly initialize the struct's member variables to. struct S { int i = 7; string s = "hello"; } S.init has a value of 7 for i and "hello" for s. Unfortunately, I don't believe that declaring an init function or property is currently disallowed, but if it affects S.init, it's a bug. - Jonathan M Davis
Aug 23 2012
It would be great if you could declare your own .init as you can atm with "new" (http://dlang.org/class.html#allocators). For example: class Foo { public: init() { this = new typeof(this)(); } } So you could avoid a null declaration by default. :)
Aug 23 2012
On 23-Aug-12 22:44, Namespace wrote:It would be great if you could declare your own .init as you can atm with "new" (http://dlang.org/class.html#allocators).Read on : Note: Class allocators are deprecated in D2.For example: class Foo { public: init() { this = new typeof(this)(); } } So you could avoid a null declaration by default. :)-- Olshansky Dmitry
Aug 23 2012
But to write your own init property would still be nice, or not?
Aug 23 2012
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. -- Olshansky Dmitry
Aug 23 2012
On 08/23/2012 12:38 PM, Dmitry Olshansky wrote:On 23-Aug-12 23:33, Namespace wrote: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. AliBut 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.
Aug 23 2012
On Thursday, August 23, 2012 21:33:57 Namespace wrote:But to write your own init property would still be nice, or not?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
Aug 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 DavisMy idea was to declare your own .init in a class, not in a struct.
Aug 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
Aug 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 DavisThat 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.
Aug 23 2012
On Friday, August 24, 2012 01:35:56 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 DavisIf 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 DavisThat 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.
Aug 23 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 DavisBut 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?
Aug 23 2012
On Friday, August 24, 2012 02:00:22 Namespace wrote: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 DavisI 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 DavisBut 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?
Aug 23 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?
Aug 24 2012
On 08/24/2012 09:39 AM, nocide wrote:Am 23.08.2012 19:15, schrieb nocide:Yes.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?
Aug 24 2012