www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - using .init reliably

reply Cauterite <cauterite gmail.com> writes:
How can I get the initial value of an arbitrary type? Since any 
struct can override it, .init is not reliable:

struct Z {
	enum init = 6;
	string val = `asdf`;
};
assert(Z.init == 6);
assert(typeof(Z()).init == 6);

I know I could use
*(cast(Z*) typeid(Z).initializer.ptr)
but that doesn't work in CTFE (because the typeinfo doesn't exist 
yet).

Z() is obviously not reliable either since it can override static 
opCall.
Aug 26 2016
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, August 26, 2016 08:59:55 Cauterite via Digitalmars-d-learn wrote:
 How can I get the initial value of an arbitrary type? Since any
 struct can override it, .init is not reliable:

 struct Z {
   enum init = 6;
   string val = `asdf`;
 };
 assert(Z.init == 6);
 assert(typeof(Z()).init == 6);

 I know I could use
 *(cast(Z*) typeid(Z).initializer.ptr)
 but that doesn't work in CTFE (because the typeinfo doesn't exist
 yet).

 Z() is obviously not reliable either since it can override static
 opCall.
Nothing should ever override init. If it does, then it should be fixed so that it doesn't. It was an oversight that it was ever allowed, and I believe that there's a bug report for it. You're supposed to be able to depend on .init existing. Default initialization for structs can be disabled via disable this(); but even then, the init member still exists (it just isn't used for default initialization). All types have an init property, and it's critical that that be the case. There's a lot of code (including in druntime and Phobos) which relies on that fact. So, just use .init, and if a type incorrectly defines init, then it's just not going not play nicely, and it needs to be fixed. And I expect that it will become an error at some point in the future to define an init member for a user-defined type, at which point, there won't be any choice about fixing it. - Jonathan M Davis
Aug 26 2016
next sibling parent reply Cauterite <cauterite gmail.com> writes:
On Friday, 26 August 2016 at 09:48:00 UTC, Jonathan M Davis wrote:
 And I expect that it will become an error at some point in the 
 future to define an init member for a user-defined type, at 
 which point, there won't be any choice about fixing it.
I might take a crack at this patch. Sounds pretty trivial.
Aug 26 2016
next sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, August 26, 2016 10:52:47 Cauterite via Digitalmars-d-learn wrote:
 On Friday, 26 August 2016 at 09:48:00 UTC, Jonathan M Davis wrote:
 And I expect that it will become an error at some point in the
 future to define an init member for a user-defined type, at
 which point, there won't be any choice about fixing it.
I might take a crack at this patch. Sounds pretty trivial.
The key thing to keep in mind is that it needs to be deprecated first rather than just simply made an error (in order to avoid breaking existing code without warning), which may or may not make it more complicated. I'm not familiar with much of the compiler's internals. Regardless, it would be great if we could move towards making it illegal to define init for a type, since it's a definitely problem that it's been possible. - Jonathan M Davis
Aug 26 2016
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 8/26/16 6:52 AM, Cauterite wrote:
 On Friday, 26 August 2016 at 09:48:00 UTC, Jonathan M Davis wrote:
 And I expect that it will become an error at some point in the future
 to define an init member for a user-defined type, at which point,
 there won't be any choice about fixing it.
I might take a crack at this patch. Sounds pretty trivial.
FYI, you cannot make this patch until we fully deprecate the use of TypeInfo.init: https://github.com/dlang/druntime/blob/master/src/object.d#L294 So at least until 2.075. -Steve
Aug 26 2016
parent Cauterite <cauterite gmail.com> writes:
On Friday, 26 August 2016 at 15:14:42 UTC, Steven Schveighoffer 
wrote:
 FYI, you cannot make this patch until we fully deprecate the 
 use of TypeInfo.init: 
 https://github.com/dlang/druntime/blob/master/src/object.d#L294

 So at least until 2.075.

 -Steve
Ah yes, good thinking. I'll keep that in mind.
Aug 26 2016
prev sibling parent reply Johan Engelen <j j.nl> writes:
On Friday, 26 August 2016 at 09:48:00 UTC, Jonathan M Davis wrote:
 
 You're supposed to be able to depend on .init existing. Default 
 initialization for structs can be disabled via

  disable this();

 but even then, the init member still exists (it just isn't used 
 for default initialization).
From what I remember, the last time I looked at ` disable this();`: it prevents the user from creating a default initialized struct. However whenever (compiler internally) the struct needs initialization, `.init` is still used. And thus it is also used at the start of any constructor the user writes. Don't take my word for it: have a look at asm output, or easier: LCD's LLVM IR output. -Johan
Aug 26 2016
parent Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, August 26, 2016 11:20:56 Johan Engelen via Digitalmars-d-learn 
wrote:
 On Friday, 26 August 2016 at 09:48:00 UTC, Jonathan M Davis wrote:
 You're supposed to be able to depend on .init existing. Default
 initialization for structs can be disabled via

  disable this();

 but even then, the init member still exists (it just isn't used
 for default initialization).
From what I remember, the last time I looked at ` disable this();`: it prevents the user from creating a default initialized struct. However whenever (compiler internally) the struct needs initialization, `.init` is still used. And thus it is also used at the start of any constructor the user writes. Don't take my word for it: have a look at asm output, or easier: LCD's LLVM IR output.
I expect that that's true. The key thing is that if that if default initialization is disabled, then you can't do something like MyType mt; But init itself is pretty integral to the language, so it's still needed for other stuff. And it would be downright brutal if you couldn't depend on init to exist for metaprogramming - which is what the OP was afraid of. - Jonathan M Davis
Aug 26 2016