digitalmars.D - String to boolean inconsistency
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (6/6) Dec 11 2010 string s = "";
- Ellery Newcomer (2/8) Dec 11 2010
- Simen kjaeraas (6/7) Dec 11 2010 '[] is null' compares ptr and length, while '[] == null' compares only
- Simen kjaeraas (7/12) Dec 11 2010 To actually answer your question, == calls opEquals for classes, and
- Andrej Mitrovic (10/16) Dec 11 2010 The first one should fail since the string has length 0. If you use an
- Andrej Mitrovic (14/33) Dec 11 2010 Actually I'm having a hard time understanding this:
- Simen kjaeraas (20/33) Dec 11 2010 Try adding writeln( s.ptr ); in there. Should probably give you an
- spir (10/13) Dec 12 2010 .dup & .idup should not change a string's truth value. For sure, _this_ ...
- Simen kjaeraas (8/17) Dec 12 2010 I'm not sure I agree here. It seems foolish to me to allocate 16 bytes (...
- Jonathan M Davis (74/79) Dec 11 2010 A null array and an empty array are essentially the same thing as far as...
- Simen kjaeraas (11/18) Dec 11 2010 Actually, that is:
- Jonathan M Davis (5/27) Dec 11 2010 Good point. Though actually, I don't think that that's quite right eithe...
- Jonathan M Davis (12/41) Dec 11 2010 On further inspection, it looks like capacity is not actually part of th...
- Jonathan M Davis (8/93) Dec 11 2010 bly
- Andrej Mitrovic (11/101) Dec 11 2010 D
- spir (8/30) Dec 12 2010 Is an empty array in general supposed to be false? (I thought that was w...
string s = ""; assert(s); // ok assert(s != null); // fails I guess that's a bug. But which one is right? -- Tomek
Dec 11 2010
I forget, why are we supposed to use is instead of == with null? On 12/11/2010 08:18 PM, Tomek Sowiński wrote:string s = ""; assert(s); // ok assert(s != null); // fails I guess that's a bug. But which one is right? -- Tomek
Dec 11 2010
Ellery Newcomer <ellery-newcomer utulsa.edu> wrote:I forget, why are we supposed to use is instead of == with null?'[] is null' compares ptr and length, while '[] == null' compares only the length. Weirdly though, '[] is null' is false for ptr == 0, length != 0. Not likely to happen much in practice. -- Simen
Dec 11 2010
Simen kjaeraas <simen.kjaras gmail.com> wrote:Ellery Newcomer <ellery-newcomer utulsa.edu> wrote:To actually answer your question, == calls opEquals for classes, and that is called on both lhs and rhs. null.opEquals however, segfaults. is, on the other hand, compares pointer equality, without caring for the details of what opEquals wants to do. -- SimenI forget, why are we supposed to use is instead of == with null?'[] is null' compares ptr and length, while '[] == null' compares only the length. Weirdly though, '[] is null' is false for ptr == 0, length != 0. Not likely to happen much in practice.
Dec 11 2010
The first one should fail since the string has length 0. If you use an .idup you would get the correct results: void main() { string s =3D "".idup; assert(s); // fails assert(s !=3D null); // ok } So I guess it's a bug. On 12/12/10, Tomek Sowi=F1ski <just ask.me> wrote:string s =3D ""; assert(s); // ok assert(s !=3D null); // fails I guess that's a bug. But which one is right? -- Tomek
Dec 11 2010
Actually I'm having a hard time understanding this: void main() { string s =3D ""; assert(s); // pass, but why? assert(s !is null); // pass } void main() { string s =3D "".idup; assert(s); // fail assert(s !is null); // pass } On 12/12/10, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:The first one should fail since the string has length 0. If you use an .idup you would get the correct results: void main() { string s =3D "".idup; assert(s); // fails assert(s !=3D null); // ok } So I guess it's a bug. On 12/12/10, Tomek Sowi=F1ski <just ask.me> wrote:string s =3D ""; assert(s); // ok assert(s !=3D null); // fails I guess that's a bug. But which one is right? -- Tomek
Dec 11 2010
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Actually I'm having a hard time understanding this: void main() { string s = ""; assert(s); // pass, but why? assert(s !is null); // pass } void main() { string s = "".idup; assert(s); // fail assert(s !is null); // pass }Try adding writeln( s.ptr ); in there. Should probably give you an indication of what is and == do. Answer: == null: Length P ==0 !=0 t ==0 T F r !=0 T F is null: Length P ==0 !=0 t ==0 T F r !=0 F F Where T and F stand for true and false, respectively. So likely, idup on an empty string returns an array with null ptr and 0 length, while "" is 'allocated' in the data segment, and thus given a ptr value. -- Simen
Dec 11 2010
On Sun, 12 Dec 2010 04:00:36 +0100 "Simen kjaeraas" <simen.kjaras gmail.com> wrote:So likely, idup on an empty string returns an array with null ptr and 0 length, while "" is 'allocated' in the data segment, and thus given a ptr value..dup & .idup should not change a string's truth value. For sure, _this_ is = a bug. I think explicite empty strings/arrays should not have null pointers, as op= posed to uninitialised strings/arrays. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Dec 12 2010
spir <denis.spir gmail.com> wrote:On Sun, 12 Dec 2010 04:00:36 +0100 "Simen kjaeraas" <simen.kjaras gmail.com> wrote:I'm not sure I agree here. It seems foolish to me to allocate 16 bytes (the minimum allocation size for the GC) for an empty array. Of course, "" is not really an empty array. Rather, it is the equivalent of "\n"[0..$-1]. That said, I think cast(bool)array should be true only in the cases where both ptr and length != 0; -- SimenSo likely, idup on an empty string returns an array with null ptr and 0 length, while "" is 'allocated' in the data segment, and thus given a ptr value..dup & .idup should not change a string's truth value. For sure, _this_ is a bug. I think explicite empty strings/arrays should not have null pointers, as opposed to uninitialised strings/arrays.
Dec 12 2010
On Saturday 11 December 2010 18:18:54 Tomek Sowi=F1ski wrote:string s =3D ""; assert(s); // ok assert(s !=3D null); // fails =20 I guess that's a bug. But which one is right?A null array and an empty array are essentially the same thing as far as D = is=20 concerned. I believe that the only difference is whether "is null" returns = true=20 or not. So, this program import std.range; import std.stdio; void main() { string s =3D ""; writefln("[%s]", s); writeln(s is null); writeln(s =3D=3D null); writeln(s.empty); writeln(); string t =3D null; writefln("[%s]", t); writeln(t is null); writeln(t =3D=3D null); writeln(t.empty); } prints [] false true true [] true true true "=3D=3D" is _not_ the correct operator to use to check for null anyway. "i= s" is the=20 correct operator for that. This behavior is intended. Arrays are actually something like this under th= e=20 hood: struct array(T) { T* arr; size_t length; } By declaring an array to be null, all you're doing is setting arr to null.= =20 std.range.empty() will check length and ignore arr. "=3D=3D" will presumabl= y only=20 check arr if the length of the two arrays is the same. If they are the same= ,=20 then each element is checked fore equality. But if their length is zero, th= en=20 you don't need to check any elements. By doing something like assert("" =3D=3D null) you're likely creating an array which has whose arr value is non-null (but = it's=20 not actually part of the array; the memory there is extra capacity which wi= ll be=20 used if/when you append to the array; it avoids extra memory re-allocations= that=20 way) and an array whose arr value is null. Both will have their lengths be = 0. When "is null" is used, it checks that arr is null. If "=3D=3D" is used, it= checks=20 whether the elements of the two arrays are the same. Since they have the sa= me=20 length, that would mean iterating through all of their elements to verify t= hat=20 each element is the same. But since there are no elements in either, no ele= ments=20 get checked. The fact that the "" array has extra capacity is irrelevant. I= t's=20 not part of the array, just arr. So, the fact that assert("" !=3D null); fails is intended. It's a result of how arrays are designed. =2D Jonathan M Davis
Dec 11 2010
Jonathan M Davis <jmdavisProg gmx.com> wrote:This behavior is intended. Arrays are actually something like this under the hood: struct array(T) { T* arr; size_t length; }Actually, that is: struct array(T) { size_t length; T* ptr; } To get the layout and names right. ( http://digitalmars.com/d/2.0/abi.html ) -- Simen
Dec 11 2010
On Saturday 11 December 2010 19:08:33 Simen kjaeraas wrote:Jonathan M Davis <jmdavisProg gmx.com> wrote:Good point. Though actually, I don't think that that's quite right either, because it has capacity as well. It seems like there's an error in the documentation. - Jonathan M DavisThis behavior is intended. Arrays are actually something like this under the hood: struct array(T) { T* arr; size_t length; }Actually, that is: struct array(T) { size_t length; T* ptr; } To get the layout and names right. ( http://digitalmars.com/d/2.0/abi.html )
Dec 11 2010
On Saturday 11 December 2010 19:16:29 Jonathan M Davis wrote:On Saturday 11 December 2010 19:08:33 Simen kjaeraas wrote:On further inspection, it looks like capacity is not actually part of the array struct. It's an external property function which uses garbage collector voodoo to determine the array's capacity. And it looks like the actual struct looks like this (in rt.lifetime in druntime): struct Array2 { size_t length; void* ptr; } So, it's not even templatized. - Jonathan M DavisJonathan M Davis <jmdavisProg gmx.com> wrote:Good point. Though actually, I don't think that that's quite right either, because it has capacity as well. It seems like there's an error in the documentation.This behavior is intended. Arrays are actually something like this under the hood: struct array(T) { T* arr; size_t length; }Actually, that is: struct array(T) { size_t length; T* ptr; } To get the layout and names right. ( http://digitalmars.com/d/2.0/abi.html )
Dec 11 2010
On Saturday 11 December 2010 19:00:55 Jonathan M Davis wrote:On Saturday 11 December 2010 18:18:54 Tomek Sowi=F1ski wrote:"is"string s =3D ""; assert(s); // ok assert(s !=3D null); // fails =20 I guess that's a bug. But which one is right?=20 A null array and an empty array are essentially the same thing as far as D is concerned. I believe that the only difference is whether "is null" returns true or not. So, this program =20 import std.range; import std.stdio; =20 void main() { string s =3D ""; =20 writefln("[%s]", s); writeln(s is null); writeln(s =3D=3D null); writeln(s.empty); writeln(); =20 string t =3D null; =20 writefln("[%s]", t); writeln(t is null); writeln(t =3D=3D null); writeln(t.empty); } =20 =20 prints =20 [] false true true =20 [] true true true =20 =20 "=3D=3D" is _not_ the correct operator to use to check for null anyway. =is the correct operator for that. =20 This behavior is intended. Arrays are actually something like this under the hood: =20 struct array(T) { T* arr; size_t length; } =20 =20 By declaring an array to be null, all you're doing is setting arr to null. std.range.empty() will check length and ignore arr. "=3D=3D" will presuma=blyonly check arr if the length of the two arrays is the same. If they are the same, then each element is checked fore equality. But if their length is zero, then you don't need to check any elements. By doing something like =20 assert("" =3D=3D null) =20 you're likely creating an array which has whose arr value is non-null (but it's not actually part of the array; the memory there is extra capacity which will be used if/when you append to the array; it avoids extra memory re-allocations that way) and an array whose arr value is null. Both will have their lengths be 0. =20 When "is null" is used, it checks that arr is null. If "=3D=3D" is used, =itchecks whether the elements of the two arrays are the same. Since they have the same length, that would mean iterating through all of their elements to verify that each element is the same. But since there are no elements in either, no elements get checked. The fact that the "" array has extra capacity is irrelevant. It's not part of the array, just arr. So, the fact that =20 assert("" !=3D null); =20 fails is intended. It's a result of how arrays are designed.On reflection, I should have used the name ptr instead of array, since that= _is_=20 its actual name. It slipped my mind I guess... =2D Jonathan M Davis
Dec 11 2010
Coolio. I should pay a visit to druntime.. sometime. :) On 12/12/10, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Saturday 11 December 2010 19:00:55 Jonathan M Davis wrote:DOn Saturday 11 December 2010 18:18:54 Tomek Sowi=F1ski wrote:string s =3D ""; assert(s); // ok assert(s !=3D null); // fails I guess that's a bug. But which one is right?A null array and an empty array are essentially the same thing as far as="is"is concerned. I believe that the only difference is whether "is null" returns true or not. So, this program import std.range; import std.stdio; void main() { string s =3D ""; writefln("[%s]", s); writeln(s is null); writeln(s =3D=3D null); writeln(s.empty); writeln(); string t =3D null; writefln("[%s]", t); writeln(t is null); writeln(t =3D=3D null); writeln(t.empty); } prints [] false true true [] true true true "=3D=3D" is _not_ the correct operator to use to check for null anyway.=l.is the correct operator for that. This behavior is intended. Arrays are actually something like this under the hood: struct array(T) { T* arr; size_t length; } By declaring an array to be null, all you're doing is setting arr to nul=ablystd.range.empty() will check length and ignore arr. "=3D=3D" will presum=honly check arr if the length of the two arrays is the same. If they are the same, then each element is checked fore equality. But if their lengt=utis zero, then you don't need to check any elements. By doing something like assert("" =3D=3D null) you're likely creating an array which has whose arr value is non-null (b=ryit's not actually part of the array; the memory there is extra capacity which will be used if/when you append to the array; it avoids extra memo=itre-allocations that way) and an array whose arr value is null. Both will have their lengths be 0. When "is null" is used, it checks that arr is null. If "=3D=3D" is used,=atchecks whether the elements of the two arrays are the same. Since they have the same length, that would mean iterating through all of their elements to verify that each element is the same. But since there are no elements in either, no elements get checked. The fact that the "" array has extra capacity is irrelevant. It's not part of the array, just arr. So, the fact that assert("" !=3D null); fails is intended. It's a result of how arrays are designed.On reflection, I should have used the name ptr instead of array, since th=_is_ its actual name. It slipped my mind I guess... - Jonathan M Davis
Dec 11 2010
On Sun, 12 Dec 2010 03:47:02 +0100 Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:The first one should fail since the string has length 0. If you use an .idup you would get the correct results: =20 void main() { string s =3D "".idup; assert(s); // fails assert(s !=3D null); // ok } =20 So I guess it's a bug. =20 On 12/12/10, Tomek Sowi=C5=84ski <just ask.me> wrote:Is an empty array in general supposed to be false? (I thought that was wron= g in D.) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.comstring s =3D ""; assert(s); // ok assert(s !=3D null); // fails I guess that's a bug. But which one is right? -- Tomek
Dec 12 2010