www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is an automatic string variable a dynamic array in the sense of sec.

reply kdevel <kdevel vogtner.de> writes:
The rule [1] states:

     For [...] dynamic arrays, identity is defined as referring to 
the same
     array elements and the same number of elements.

[BTW: Every two arrays having the same elements implies that they 
also have the same **number** of elements. Hence the second 
condition is redundant.]

In this piece of code [2]:

```
    void main ()
    {
       string s = null;
       string t = "";
       assert (s is t);
    }
```

the assertion trips although both conditions of the given rule 
are met.

The second condition of the rule is true: Both arrays have the 
same number of elements (zero). For the first condition to be 
false it requires an index position at which the elements of both 
arrays differ. Since there is no such position the first 
condition is **not** false, meaning it is also true.

Therefor the documentation does not document the actual behavior 
of D implementations (checked dmd and gdc). The issue is not 
restricted to the string type.



[1] https://dlang.org/spec/expression.html#identity_expressions
[2] https://issues.dlang.org/show_bug.cgi?id=17623
Jul 15 2022
next sibling parent ag0aep6g <anonymous example.com> writes:
On Friday, 15 July 2022 at 13:34:03 UTC, kdevel wrote:
 The rule [1] states:

     For [...] dynamic arrays, identity is defined as referring 
 to the same
     array elements and the same number of elements.

 [BTW: Every two arrays having the same elements implies that 
 they also have the same **number** of elements. Hence the 
 second condition is redundant.]
"Referring to the same array elements" is supposed to mean that the `.ptr` is the same. Maybe the phrasing can be improved.
Jul 15 2022
prev sibling next sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Friday, 15 July 2022 at 13:34:03 UTC, kdevel wrote:
 In this piece of code [2]:

 ```
    void main ()
    {
       string s = null;
       string t = "";
       assert (s is t);
    }
 ```

 the assertion trips although both conditions of the given rule 
 are met.
```d string s, t; void main() { assert(s is t); assert(s is null); assert(t is null); s.length = 2; t.length = 2; assert(!is(s == t)); // true (check identy) assert(s == t); // true (check content) // because they are different strings: assert(is(string : typeof(s))); assert(is(string : typeof(t))); // but it can be same: auto u = s[0..2]; // a dynamic array assert(s is u); // true assert(s == u); // right on import std.stdio; // see following: writeln(cast(ubyte[])s); // [255, 255] writeln(cast(ubyte[])t); // [255, 255] writeln(cast(ubyte[])u); // [255, 255] ``` SDB%79
Jul 15 2022
prev sibling parent reply Mathias LANG <geod24 gmail.com> writes:
On Friday, 15 July 2022 at 13:34:03 UTC, kdevel wrote:
 the assertion trips although both conditions of the given rule 
 are met.
Another way to express `is` would be to say: their immediate value are binary equivalent. For value type it's simple (it also means that `float.init is float.init` but not all NaN will be equal obviously), but for reference type, it's just comparing their pointer (and for arrays, their length). Note that there is a very subtle difference between `null` and `""`, and it matters. `null` means `.ptr is null && .length == 0` while `""` means `.ptr !is null && .length == 0`. This is crazy, right ? Well no, it's on purpose, because string literals have a `\0` past their end, to ensure compatibility with C (something we had overwhelming evidence of being a good thing). So the "subtle difference" is that `assert("".ptr + 1 == 0);`.
Jul 16 2022
next sibling parent Dukc <ajieskola gmail.com> writes:
On Saturday, 16 July 2022 at 13:03:42 UTC, Mathias LANG wrote:
 So the "subtle difference" is that `assert("".ptr + 1 == 0);`.
You mean `assert("".ptr[0] == 0)`, right?
Jul 16 2022
prev sibling next sibling parent kdevel <kdevel vogtner.de> writes:
On Saturday, 16 July 2022 at 13:03:42 UTC, Mathias LANG wrote:
 On Friday, 15 July 2022 at 13:34:03 UTC, kdevel wrote:
 the assertion trips although both conditions of the given rule 
 are met.
Another way to express `is` would be to say [...]
I only want to point out that the current documentation does not document the actual behavior. Meanwhile I proposed an corrected statement in the bugzilla issue. And I am fully aware what is going on in the engine room. Thanks for your participation anyway.
Jul 17 2022
prev sibling parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Saturday, 16 July 2022 at 13:03:42 UTC, Mathias LANG wrote:
 Another way to express `is` would be to say: their immediate 
 value are binary equivalent. For value type it's simple (it 
 also means that `float.init is float.init` but not all NaN will 
 be equal obviously), but for reference type, it's just 
 comparing their pointer (and for arrays, their length).
I wouldn’t use the term “binary equivalent”. It sounds… wrong – and I’ll tell you why. We’re in precise-definition territory. Here, “equivalent” is not the same as “equal”. If I’m not horribly mistaken, the `is` operator for value types plainly compares the bytes, that is, the bytes are equal. I could imagine a definition for “binary equivalent” that is different from “binary equal”: Padding bits are ignored and if the struct has internal pointers, those point to the same offset, respectively. Of course, that is a vague term, as “equivalent” usually is in contrast to “equal”.
Jul 19 2022