www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is there a way to see if .init has been set by the user?

reply "simendsjo" <simendsjo gmail.com> writes:
I want to know if a variable has changed .init, but I don't know 
if it's possible if the .init value is the same. Does anyone have 
a solution for this?

     int a;
     int b = 0;
     pragma(msg, a.init); // 0
     pragma(msg, b.init); // 0
     // how can I see that b has "= 0"?
Sep 21 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
simendsjo:

 I want to know if a variable has changed .init, but I don't 
 know if it's possible if the .init value is the same. Does 
 anyone have a solution for this?

     int a;
     int b = 0;
     pragma(msg, a.init); // 0
     pragma(msg, b.init); // 0
     // how can I see that b has "= 0"?
init is part of a type and you can't change it. a and by are both ints, and in both cases int.init is 0. I think there is no simple way to know if a variable has being default-initialized or not. Why do you want to know it? Bye, bearophile
Sep 21 2013
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/21/13, bearophile <bearophileHUGS lycos.com> wrote:
 I think there is no simple
 way to know if a variable has being default-initialized or not.
 Why do you want to know it?
There is however a way to extract it if it's a part of an aggregate: ----- struct S { int x = 1; } void main() { static assert(S.x.init == 0); static assert(S.init.x == 1); } -----
Sep 21 2013
parent reply "simendsjo" <simendsjo gmail.com> writes:
On Saturday, 21 September 2013 at 12:50:20 UTC, Andrej Mitrovic 
wrote:
 On 9/21/13, bearophile <bearophileHUGS lycos.com> wrote:
 I think there is no simple
 way to know if a variable has being default-initialized or not.
 Why do you want to know it?
There is however a way to extract it if it's a part of an aggregate: ----- struct S { int x = 1; } void main() { static assert(S.x.init == 0); static assert(S.init.x == 1); } -----
I'm though of using if for aggregates, yes. But this doesn't handle the case where you set the same value is T.init.
Sep 21 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Saturday, 21 September 2013 at 13:30:19 UTC, simendsjo wrote:
 I'm though of using if for aggregates, yes. But this doesn't 
 handle the case where you set the same value is T.init.
I don't think those two case are any different from the type system point of view, manual or default.
Sep 21 2013
parent reply "simendsjo" <simendsjo gmail.com> writes:
On Saturday, 21 September 2013 at 13:38:44 UTC, Dicebot wrote:
 On Saturday, 21 September 2013 at 13:30:19 UTC, simendsjo wrote:
 I'm though of using if for aggregates, yes. But this doesn't 
 handle the case where you set the same value is T.init.
I don't think those two case are any different from the type system point of view, manual or default.
Need some __traits(hasUserSuppliedInit, T) then :)
Sep 21 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Saturday, 21 September 2013 at 13:48:00 UTC, simendsjo wrote:
 On Saturday, 21 September 2013 at 13:38:44 UTC, Dicebot wrote:
 On Saturday, 21 September 2013 at 13:30:19 UTC, simendsjo 
 wrote:
 I'm though of using if for aggregates, yes. But this doesn't 
 handle the case where you set the same value is T.init.
I don't think those two case are any different from the type system point of view, manual or default.
Need some __traits(hasUserSuppliedInit, T) then :)
I am not sure those differ even at compiler level (other than at syntax stage) - why would you need it?
Sep 21 2013
parent reply "simendsjo" <simendsjo gmail.com> writes:
On Saturday, 21 September 2013 at 13:55:00 UTC, Dicebot wrote:
 On Saturday, 21 September 2013 at 13:48:00 UTC, simendsjo wrote:
 On Saturday, 21 September 2013 at 13:38:44 UTC, Dicebot wrote:
 On Saturday, 21 September 2013 at 13:30:19 UTC, simendsjo 
 wrote:
 I'm though of using if for aggregates, yes. But this doesn't 
 handle the case where you set the same value is T.init.
I don't think those two case are any different from the type system point of view, manual or default.
Need some __traits(hasUserSuppliedInit, T) then :)
I am not sure those differ even at compiler level (other than at syntax stage) - why would you need it?
I was thinking of "query by example". If a field has been set, it should be used in a where clause. But if I cannot see the difference between int.init and 0 for instance, it is impossible to get it right. It's possible to solve this using UDAs of course.
Sep 21 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
On Saturday, 21 September 2013 at 14:11:44 UTC, simendsjo wrote:
 On Saturday, 21 September 2013 at 13:55:00 UTC, Dicebot wrote:
 On Saturday, 21 September 2013 at 13:48:00 UTC, simendsjo 
 wrote:
 On Saturday, 21 September 2013 at 13:38:44 UTC, Dicebot wrote:
 On Saturday, 21 September 2013 at 13:30:19 UTC, simendsjo 
 wrote:
 I'm though of using if for aggregates, yes. But this 
 doesn't handle the case where you set the same value is 
 T.init.
I don't think those two case are any different from the type system point of view, manual or default.
Need some __traits(hasUserSuppliedInit, T) then :)
I am not sure those differ even at compiler level (other than at syntax stage) - why would you need it?
I was thinking of "query by example". If a field has been set, it should be used in a where clause. But if I cannot see the difference between int.init and 0 for instance, it is impossible to get it right. It's possible to solve this using UDAs of course.
0 and int.init is the same. ;)
Sep 21 2013
prev sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 21 September 2013 at 11:35:11 UTC, bearophile wrote:
 init is part of a type and you can't change it.

 Bye,
 bearophile
Well, D wouldn't be D, if it did not allow something like this for aggregate types: import core.stdc.string, std.stdio; pure hack(T)(T value) if (is(T == class)) { byte[] init_mem = new byte[T.classinfo.init.length]; memcpy(init_mem.ptr, cast(byte*)value, T.classinfo.init.length); T.classinfo.init = init_mem; } class A { int a; } pure foo(int val) { A a = new A; a.a++; hack(a); return a.a + val; } void main() { writeln(0.foo, 0.foo, 0.foo); // prints 1,2,3 } And taking into accout some additional runtime magic, assertion below may fail: class A { int i = 5; } struct S { A a;} S s; assert(s.a is null);
Sep 21 2013
prev sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 21 September 2013 at 11:13:57 UTC, simendsjo wrote:
 I want to know if a variable has changed .init, but I don't 
 know if it's possible if the .init value is the same. Does 
 anyone have a solution for this?

     int a;
     int b = 0;
     pragma(msg, a.init); // 0
     pragma(msg, b.init); // 0
     // how can I see that b has "= 0"?
Strictly speaking this is an ill-posed question. Are talking about testing at runtime whether some variable was changed from init to some non-default value?
Sep 21 2013
parent reply "simendsjo" <simendsjo gmail.com> writes:
On Saturday, 21 September 2013 at 15:43:11 UTC, Maxim Fomin wrote:
 On Saturday, 21 September 2013 at 11:13:57 UTC, simendsjo wrote:
 I want to know if a variable has changed .init, but I don't 
 know if it's possible if the .init value is the same. Does 
 anyone have a solution for this?

    int a;
    int b = 0;
    pragma(msg, a.init); // 0
    pragma(msg, b.init); // 0
    // how can I see that b has "= 0"?
Strictly speaking this is an ill-posed question. Are talking about testing at runtime whether some variable was changed from init to some non-default value?
No, at compile-time. It's trivial to see if init is changed, but I want to see if it's set even if it's to T.init.
Sep 21 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 21 September 2013 at 16:09:35 UTC, simendsjo wrote:
 On Saturday, 21 September 2013 at 15:43:11 UTC, Maxim Fomin 
 wrote:
 On Saturday, 21 September 2013 at 11:13:57 UTC, simendsjo 
 wrote:
 I want to know if a variable has changed .init, but I don't 
 know if it's possible if the .init value is the same. Does 
 anyone have a solution for this?

   int a;
   int b = 0;
   pragma(msg, a.init); // 0
   pragma(msg, b.init); // 0
   // how can I see that b has "= 0"?
Strictly speaking this is an ill-posed question. Are talking about testing at runtime whether some variable was changed from init to some non-default value?
No, at compile-time. It's trivial to see if init is changed, but I want to see if it's set even if it's to T.init.
I think there is a misunderstanding in your "a.init" and "b.init": This is just calling a static property on an instance. It's no different from T.init. It *won't* tell you what a/b was initially initialized with. If I understand correctly, you want: int b = 3; static assert(__traits(initialValue, b) == 3); ? I don't think we have that. I'm not even sure we *can* have that.
Sep 21 2013
prev sibling parent "Dicebot" <public dicebot.lv> writes:
On Saturday, 21 September 2013 at 16:09:35 UTC, simendsjo wrote:
 On Saturday, 21 September 2013 at 15:43:11 UTC, Maxim Fomin 
 wrote:
 On Saturday, 21 September 2013 at 11:13:57 UTC, simendsjo 
 wrote:
 I want to know if a variable has changed .init, but I don't 
 know if it's possible if the .init value is the same. Does 
 anyone have a solution for this?

   int a;
   int b = 0;
   pragma(msg, a.init); // 0
   pragma(msg, b.init); // 0
   // how can I see that b has "= 0"?
Strictly speaking this is an ill-posed question. Are talking about testing at runtime whether some variable was changed from init to some non-default value?
No, at compile-time. It's trivial to see if init is changed, but I want to see if it's set even if it's to T.init.
I see. No, I don't think this feature is suitable for declarative approach abuse ;) Even if you manage to hack something, it is unlikely to be reliable, I'd recommend to stick to UDA's until compiler exposes that info.
Sep 21 2013