Thread overview
No segfault -> null == ""
Mar 31, 2009
Qian Xu
Mar 31, 2009
Frits van Bommel
Mar 31, 2009
Sergey Gromov
Mar 31, 2009
BCS
March 31, 2009
Hi All,

When I was trying to learn how char-array works, I found something unexpected.

-------------------------- code ------------------------------
module string_test;

void main()
{
  // test 1
  assert(null == "", "null is empty"); // No segfault

  // test 2
  char[] test; // test = null;
  assert(test is null, "undefined_string is null");
  assert(test == "", "undefined_string (null) is empty");
  assert(test.length == 0, "undefined_string.length == 0");

  // test 3
  test = "";
  assert(test !is null, "empty_string is NOT null");
  assert(test == "", "empty_string is empty");
  assert(test.length == 0, "empty_string.length == 0");

  // test 4
  test = "hello";
  assert(test !is null, "non_empty_string is NOT empty");
  assert(test != "", "non_empty_string is NOT empty");
  assert(test.length > 0, "non_empty_string.length > 0");
}
-------------------------- code ------------------------------

I just wondered, why the first test does not lead to a segfault. Is this an undocumented compiler feature? I have tested it with gdc and gdmd. Both no segfault.


--Qian
March 31, 2009
Please remember, strings are not objects.

Therefore, a comparison against null does not cause a segfault, as it might with an object.  In the case of arrays, "test == null" and "test is null" should be the same operation.

In contrast, if you had null == new Object(), you would've seen:

name.d(6): Error: use 'is' instead of '==' when comparing with null

-[Unknown]


Qian Xu wrote:
> Hi All,
> 
> When I was trying to learn how char-array works, I found something
> unexpected.
> 
> -------------------------- code ------------------------------
> module string_test;
> 
> void main()
> {
>   // test 1
>   assert(null == "", "null is empty"); // No segfault
> 
>   // test 2
>   char[] test; // test = null;
>   assert(test is null, "undefined_string is null");
>   assert(test == "", "undefined_string (null) is empty");
>   assert(test.length == 0, "undefined_string.length == 0");
> 
>   // test 3
>   test = "";
>   assert(test !is null, "empty_string is NOT null");
>   assert(test == "", "empty_string is empty");
>   assert(test.length == 0, "empty_string.length == 0");
> 
>   // test 4
>   test = "hello";
>   assert(test !is null, "non_empty_string is NOT empty");
>   assert(test != "", "non_empty_string is NOT empty");
>   assert(test.length > 0, "non_empty_string.length > 0");
> }
> -------------------------- code ------------------------------
> 
> I just wondered, why the first test does not lead to a segfault. Is this an
> undocumented compiler feature? I have tested it with gdc and gdmd. Both no
> segfault.
> 
> 
> --Qian
March 31, 2009
Unknown W. Brackets wrote:
> In the case of arrays, "test == null" and "test is null" should be the same operation.

They're not the same operation. (Though there was quite a large debate on these newsgroups a while back because a lot of people thought they *should* be, as you said)

The difference:
'==', when used on arrays, compares first the length and then all elements (only if the lengths are equal, otherwise the result is already known).
Since 'null' contains no elements, only the length gets compared for (null == test). Either the other array is also empty and they're therefore equal, or the other array isn't and they aren't.
'is', when used on arrays, compares both the length and the pointer. It only returns true if both are equal. It never looks at the elements.

So (null == ""), but (null !is "").
March 31, 2009
Tue, 31 Mar 2009 16:29:30 +0200, Qian Xu wrote:

> When I was trying to learn how char-array works, I found something unexpected.
> 
> -------------------------- code ------------------------------
> module string_test;
> 
> void main()
> {
>   // test 1
>   assert(null == "", "null is empty"); // No segfault

When you compare null to an array, null is first converted into an empty array, then a comparison takes place.  This happens because arguments to comparison operator are first converted to a common type.
March 31, 2009
Reply to Sergey,

> Tue, 31 Mar 2009 16:29:30 +0200, Qian Xu wrote:
> 
>> assert(null == "", "null is empty"); // No segfault
>
> When you compare null to an array, null is first converted into an
> empty array, then a comparison takes place.  This happens because
> arguments to comparison operator are first converted to a common type.
> 

FWIW while that may be logically correct, I don't think that's how it actually gets implemented.