September 26, 2014
On Fri, 26 Sep 2014 01:08:59 +0000
AsmMan via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> > "" has length of 0. null has length of 0. two strings without
> > content
> > are essentialy the same.
> but null has length? what's null in D?
i confused you here, sorry. what i mean is 'null string', not 'null' as
a type itself. i.e.
string a = ""; // "empty string"
string a = null; // "null string"


September 26, 2014
On Friday, 26 September 2014 at 01:09:01 UTC, AsmMan wrote:
> On Friday, 26 September 2014 at 00:53:24 UTC, ketmar via Digitalmars-d-learn wrote:
>> On Fri, 26 Sep 2014 00:24:27 +0000
>> AsmMan via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
>> wrote:
>>
>>> It made me a bit confusing. How is the implementation of string
>>> comparasion in D?
>> "" has length of 0. null has length of 0. two strings without content
>> are essentialy the same.
>
> but null has length? what's null in D?

To reinforce what ketmar is saying:

strings in D are just `immutable(char)[]` ... a simple array of immutable chars. All arrays are just (essentially) `struct Arr(T) { T* ptr; size_t length; }` ... so this differs from C# where String is actually a class. So, when we talk about `string s = null;`, the structure would look like `ptr = null; length = 0`. You can still get the length out of a "nulled out string" (or any array type for that matter). Obviously in C#, that'd give you a null pointer exception since it's a class.

When you compare equality between two different arrays in D, you're checking for if they have all of the same elements (thus, ptr being different between two arrays is irrelevant). Trivially any two strings with length 0 are equal, so there are 4 billion equivalent empty strings in D (in 32-bit mode, and 2^64 in 64 bit mode, of course).

So, if you want an empty string, you can do any one of:

`s = null;`
`s.length = 0;`
`s = "";`

and you'll be fine.
September 26, 2014
On 9/25/14 8:24 PM, AsmMan wrote:
> On Thursday, 25 September 2014 at 12:43:57 UTC, Steven
> Schveighoffer wrote:
>> On 9/25/14 2:41 AM, SlomoTheBrave wrote:
>>> On Thursday, 25 September 2014 at 05:29:37 UTC, AsmMan wrote:
>>>> Does D has C#'s string.Empty?
>>>
>>> string.init ?
>>>
>>> ----
>>>     string a;
>>>     a = string.init;
>>>     assert( a == "");
>>> ----
>>>
>>> does the job for the type string at least.
>>>
>> null also works. In fact, in the above, a is already string.init or
>> null before assigning (D always initializes variables unless asked not
>> to).
>>
>> a = null; // same as a = string.init;

> It made me a bit confusing. How is the implementation of string
> comparasion in D? (if someone could point to actual code used in
> these comparasion would be really great otherwise I'll check out
> assembly output, maybe) in no language I know of (including C#)
> "" == null is true

A string is simply an array of char in D, similar to how it is in C. It is NOT a full-blown class type, unlike many languages, C# included.

The code to compare all arrays is somewhere in the runtime, not sure exactly where, but the compiler has some tricks it can use when generating code, so it may not call those functions.

Essentially, comparison is a foreach over the length of the arrays. If they are null, then their lengths are 0. But the actual pointers may be different, it doesn't matter.

Interestingly:

string s = "";
string t = [];

Note that both are valid, because both are arrays. but...

assert(s.ptr !is null);
assert(t.ptr is null);

Why? Because string literals are special in that they actually point to null terminated memory. So "hello" is actually an array of 5 chars + a 6th '\0' char. However, the length of "hello" is set to 5. The reason for this is so you can just pass a string literal into a C function, and it works. But due to this rule, "" cannot point at null, it must point to valid memory for the terminating '\0'.

An array does not need to conform to C rules, so it can safely set the pointer to null.

If we compare s and t:

assert(s == t);
assert(s !is t);

this is because == checks to see if the arrays are *equivalent*, meaning they have the same length, and all the elements are equivalent. 'is' checks to see if the arrays are *identical*, meaning they point at the same memory.

-Steve
September 26, 2014
On Fri, Sep 26, 2014 at 02:01:22PM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote:
> On 9/25/14 8:24 PM, AsmMan wrote:
[...]
> >It made me a bit confusing. How is the implementation of string comparasion in D? (if someone could point to actual code used in these comparasion would be really great otherwise I'll check out assembly output, maybe) in no language I know of (including C#) "" == null is true
[...]

In D, it's generally a bad idea to compare arrays with null, unless you're prepared to handle a lot of implementation-specific details. Instead, you should check .length, if it's 0, the string is empty, otherwise, it's not.

If you need to distinguish between an empty string and null, you might want to consider using std.typecons.Nullable instead. It's slightly more verbose, but makes the intent of the code clearer and may lead to more maintainable code.


T

-- 
One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie. -- The Silicon Valley Tarot
1 2
Next ›   Last »