"" gives an empty string, while "".idup gives null
simendsjo
simendsjo at gmail.com
Wed Aug 3 09:50:03 PDT 2011
On 03.08.2011 18:18, Jonathan M Davis wrote:
> On Thursday 04 August 2011 00:27:12 Mike Parker wrote:
>> On 8/3/2011 11:23 PM, simendsjo wrote:
>>> On 03.08.2011 15:49, bearophile wrote:
>>>> simendsjo:
>>>>> void main() {
>>>>> assert(is(typeof("") == typeof("".idup))); // both is
>>>>> immutable(char)[]
>>>>>
>>>>> assert("" !is null);
>>>>> assert("".idup !is null); // fails - s is null. Why?
>>>>> }
>>>>
>>>> I think someone has even suggested to statically forbid "is null" on
>>>> strings :-)
>>>>
>>>> Bye,
>>>> bearophile
>>>
>>> How should I test for null if not with "is null"? There is a difference
>>> between null and empty, and avoiding this is not necessarily easy or
>>> even wanted.
>>> I couldn't find anything in the specification stating this difference.
>>> So... Is it a bug?
>>
>> This is apparently a bug. Somehow, the idup is clobbering the pointer.
>> You can see it more clearly here:
>>
>> void main()
>> {
>> assert("".ptr);
>>
>> auto s = "".idup;
>> assert(s.ptr); // boom!
>> }
>
> I don't know if it's a bug or not. The string _was_ duped. assert(s == "")
> passes. So, as far as equality goes, they're equal, and they don't point to
> the same memory. Now, you'd think that the new string would be just empty
> rather than null, but whether it's a bug or not depends exactly on what dup
> and idup are supposed to do with regards to null. It's probably just a side
> effect of how dup and idup are implemented rather than it being planned one way
> or the other. I don't know if it matters or not though. In general, I don't
> like the conflation of null and empty, but is this particular case, you _do_
> get a string which is equal to the original and which doesn't point to the
> same memory. So, I don't know whether this should be considered a bug or not.
> It depends on what dup and idup are ultimately supposed to do.
>
> - Jonathan M Davis
I would think it's a bug, but strings doesn't quite behave as regular
references anyway...
But why should dup/idup change the semantics of the array?
void main() {
// A null string or empty string works as expected
string s1;
assert(s1 is null);
assert(s1.ptr is null);
assert(s1 == ""); // We can check for empty even if it's
null, and it's equal to ""
assert(s1.length == 0); // ...and length even if it's null
s1 = "";
assert(s1 !is null);
assert(s1.ptr !is null);
assert(s1.length == 0);
assert(s1 == "");
// the same applies to null mutable arrays
char[] s2;
assert(s2 is null);
assert(s2.ptr is null);
assert(s2 == "");
assert(s2.length == 0);
// but with .dup/.idup things is different!
s2 = "".dup;
//assert(s2 !is null); // fails
//assert(s2.ptr !is null); // fails
assert(s2.length == 0); // but... s2 is null..?
assert(s2 == "");
assert(s2 == s1);
}
More information about the Digitalmars-d-learn
mailing list