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);
}