www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - is it bug?

reply drug <drug2004 bk.ru> writes:
https://run.dlang.io/is/uk0CMC
Sep 25
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 25 September 2017 at 17:44:54 UTC, drug wrote:
 https://run.dlang.io/is/uk0CMC
You didn't initialize it. It's not null, but it also isn't a valid character. D initializes chars to 0xff, which is an invalid char. Perhaps the Nullable one should have initialized to null but otherwise it looks ok.
Sep 25
parent drug <drug2004 bk.ru> writes:
25.09.2017 20:47, Adam D. Ruppe пишет:
 On Monday, 25 September 2017 at 17:44:54 UTC, drug wrote:
 https://run.dlang.io/is/uk0CMC
You didn't initialize it. It's not null, but it also isn't a valid character.
but exception is caused by using `get` on null Foo instance, not by invalid character as I can see
 
 D initializes chars to 0xff, which is an invalid char.
 
Yes, if I initialize Nullable one it works, but it means that Nullable can be constructed incorrectly by default and manual initialization is needed always?
 
 Perhaps the Nullable one should have initialized to null but otherwise 
 it looks ok.
Shouldn't Nullable one be initialized as a null by default?
Sep 25
prev sibling next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/25/17 1:44 PM, drug wrote:
 https://run.dlang.io/is/uk0CMC
Definitely a bug. -Steve
Sep 25
prev sibling parent reply drug <drug2004 bk.ru> writes:
https://run.dlang.io/is/pZwsoX

As I can see std.format.formatElement thinks Nullable!Foo is not null, 
try to get its value but it is null so fail?
Sep 25
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/25/17 2:03 PM, drug wrote:
 https://run.dlang.io/is/pZwsoX
 
 As I can see std.format.formatElement thinks Nullable!Foo is not null, 
 try to get its value but it is null so fail?
OK, so I was confused quite a bit. There are 2 problems. One is a bug, one is not. First up, the non-bug: You wrote: writeln(bar.foo.isNull); // false writeln(bar.foo); // error But bar.foo is this: struct Foo { Nullable!(char[2]) value; } And bar.foo is nullable itself. It's a nullable!Foo. It's a Nullable!Foo, that is not null, but contains a Nullable!(char[2]) that *is* null. So when you print Foo, it calls the get on it, which works, and then tries to print all its members (the default thing for std.format), and when it gets to the *value* member, it crashes. So bar.foo.isNull has no bearing on the actual error. bar.foo.value.isNull is true, and there's where the error happens. Your first example was more confusing because it wasn't named `value`, it was named `foo`! Second is the actual bug, and we don't need Bar to show it: Foo foo; writeln(foo.value); // Nullable.null writeln(foo); // error There is something different that happens when you try to print a Nullable directly, than when you print a struct containing the Nullable. So this is the reduced case. The second line should print Foo(Nullable.null), not throw an error. And yes, it has something to do with the fact that it's a char[2]. int works. char[] also fails. -Steve
Sep 25
parent reply drug <drug2004 bk.ru> writes:
25.09.2017 22:58, Steven Schveighoffer пишет:
 
 First up, the non-bug:
 
 You wrote:
 
 writeln(bar.foo.isNull); // false
 writeln(bar.foo); // error
 
 But bar.foo is this:
 
 struct Foo
 {
     Nullable!(char[2]) value;
 }
 
 And bar.foo is nullable itself. It's a nullable!Foo.
 
 It's a Nullable!Foo, that is not null, but contains a Nullable!(char[2]) 
 that *is* null.
 
 So when you print Foo, it calls the get on it, which works, and then 
 tries to print all its members (the default thing for std.format), and 
 when it gets to the *value* member, it crashes.
so the bug here is that instead of outputting "null" it tries to get null value, isn't it? And I guess that std.format process char-based types in different manner than others so we have working int, float etc arrays and failing char-based types (string, wstring, char[], static char[] and so on)
 
 So bar.foo.isNull has no bearing on the actual error. 
 bar.foo.value.isNull is true, and there's where the error happens.
 
 Your first example was more confusing because it wasn't named `value`, 
 it was named `foo`!
 
 Second is the actual bug, and we don't need Bar to show it:
 
 Foo foo;
 writeln(foo.value); // Nullable.null
 writeln(foo); // error
 
 There is something different that happens when you try to print a 
 Nullable directly, than when you print a struct containing the Nullable.
 
 So this is the reduced case. The second line should print 
 Foo(Nullable.null), not throw an error. And yes, it has something to do 
 with the fact that it's a char[2]. int works. char[] also fails.
 
 -Steve
Sep 26
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/26/17 3:13 AM, drug wrote:
 25.09.2017 22:58, Steven Schveighoffer пишет:
 First up, the non-bug:

 You wrote:

 writeln(bar.foo.isNull); // false
 writeln(bar.foo); // error

 But bar.foo is this:

 struct Foo
 {
     Nullable!(char[2]) value;
 }

 And bar.foo is nullable itself. It's a nullable!Foo.

 It's a Nullable!Foo, that is not null, but contains a 
 Nullable!(char[2]) that *is* null.

 So when you print Foo, it calls the get on it, which works, and then 
 tries to print all its members (the default thing for std.format), and 
 when it gets to the *value* member, it crashes.
so the bug here is that instead of outputting "null" it tries to get null value, isn't it?
Yes, that is the bug, as I said at the end of my message. But you had confused the issue by showing that "hey bar.foo isn't null!" which had nothing to do with the bug. It wasn't null, and wasn't improperly being treated as null. You don't need Bar at all to show the issue.
 And I guess that std.format process char-based 
 types in different manner than others so we have working int, float etc 
 arrays and failing char-based types (string, wstring, char[], static 
 char[] and so on)
It's not that simple: Nullable!(char[]) x; writeln(x); // Nullable.null; static struct Foo { Nullable!(char[]) x; } Foo foo; writeln(foo); // error So in one context, printing a nullable char[] works exactly as expected. In another context it does something different. The place where it's different needs to be diagnosed and fixed. -Steve
Sep 26
parent reply drug <drug2004 bk.ru> writes:
26.09.2017 15:16, Steven Schveighoffer пишет:
 
 Yes, that is the bug, as I said at the end of my message. But you had 
 confused the issue by showing that "hey bar.foo isn't null!" which had 
 nothing to do with the bug. It wasn't null, and wasn't improperly being 
 treated as null. You don't need Bar at all to show the issue.
I see. It just was not-enough-reduced reduced case)
 
 And I guess that std.format process char-based types in different 
 manner than others so we have working int, float etc arrays and 
 failing char-based types (string, wstring, char[], static char[] and 
 so on)
It's not that simple: Nullable!(char[]) x; writeln(x); // Nullable.null; static struct Foo { Nullable!(char[]) x; } Foo foo; writeln(foo); // error So in one context, printing a nullable char[] works exactly as expected. In another context it does something different. The place where it's different needs to be diagnosed and fixed. -Steve
Isn't it relevant to https://issues.dlang.org/show_bug.cgi?id=11730 ?
Sep 26
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/26/17 8:44 AM, drug wrote:
 26.09.2017 15:16, Steven Schveighoffer пишет:
 Nullable!(char[]) x;
 writeln(x); // Nullable.null;
 static struct Foo { Nullable!(char[]) x; }
 Foo foo;
 writeln(foo); // error

 So in one context, printing a nullable char[] works exactly as 
 expected. In another context it does something different. The place 
 where it's different needs to be diagnosed and fixed.
Isn't it relevant to https://issues.dlang.org/show_bug.cgi?id=11730 ?
I doubt it. That was associative arrays, and required a compiler fix. This is likely a slight difference in how std.format works on a struct vs. a single value. -Steve
Sep 26