www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - wstring comparison is failing

reply Brett <Brett gmail.com> writes:
cast(wstring)entry.szExeFile == Name
to!wstring(entry.szExeFile) == Name

These all fail. The strings are clearly the same. I can compare 
char by char and it works. latest D 2.088. The only thing is that 
szExeFile is a static wchar array... which shouldn't effect the 
comparison.
Sep 23 2019
next sibling parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Monday, 23 September 2019 at 20:38:03 UTC, Brett wrote:
 cast(wstring)entry.szExeFile == Name
 to!wstring(entry.szExeFile) == Name

 These all fail. The strings are clearly the same. I can compare 
 char by char and it works. latest D 2.088. The only thing is 
 that szExeFile is a static wchar array... which shouldn't 
 effect the comparison.
If you're comparing a static array, you're also comparing the bytes after the NUL character. Both of those conversions will give you a wstring with the length of the entire array, regardless of and including any NUL characters, so that's probably not what you want. fromStringz would probably be more appropriate there.
Sep 23 2019
prev sibling parent reply destructionator gmail.com writes:
On Mon, Sep 23, 2019 at 08:38:03PM +0000, Brett via Digitalmars-d-learn wrote:
 The only thing is that szExeFile is a static
 wchar array... which shouldn't effect the comparison.
are you sure about that? with a static size, the lengths of the two sides won't match...
Sep 23 2019
parent reply Brett <Brett gmail.com> writes:
On Monday, 23 September 2019 at 20:45:00 UTC, destructionator 
wrote:
 On Mon, Sep 23, 2019 at 08:38:03PM +0000, Brett via 
 Digitalmars-d-learn wrote:
 The only thing is that szExeFile is a static
 wchar array... which shouldn't effect the comparison.
are you sure about that? with a static size, the lengths of the two sides won't match...
I guess you are probably right... I was thinking that it would compare up to a null terminator. Seems kinda buggy... maybe the compiler needs to give a warning? After all, compared a fixed size array with a dynamic array then will almost always fail since it is unlikely the sizes will match... ...rather than failing silently.
Sep 23 2019
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, September 23, 2019 5:22:14 PM MDT Brett via Digitalmars-d-learn 
wrote:
 On Monday, 23 September 2019 at 20:45:00 UTC, destructionator

 wrote:
 On Mon, Sep 23, 2019 at 08:38:03PM +0000, Brett via

 Digitalmars-d-learn wrote:
 The only thing is that szExeFile is a static
 wchar array... which shouldn't effect the comparison.
are you sure about that? with a static size, the lengths of the two sides won't match...
I guess you are probably right... I was thinking that it would compare up to a null terminator. Seems kinda buggy... maybe the compiler needs to give a warning? After all, compared a fixed size array with a dynamic array then will almost always fail since it is unlikely the sizes will match... ...rather than failing silently.
D does virtually nothing with null terminators. String literals have them one index past their end so that you can pass them to C functions without D code actually seeing the null terminator, but otherwise, you have to add the null terminator when passing to C code (e.g. with toStringz or toUTFz), and you have to strip it off when getting a string from C code (e.g. with fromStringz). Other than functions specifically designed to convert to and from C strings, D code is going to treat null terminators just like any other character, because D strings are not null-terminated. - Jonathan M Davis
Sep 23 2019
prev sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Monday, 23 September 2019 at 23:22:14 UTC, Brett wrote:
 I guess you are probably right... I was thinking that it would 
 compare up to a null terminator. Seems kinda buggy... maybe the 
 compiler needs to give a warning? After all, compared a fixed 
 size array with a dynamic array then will almost always fail 
 since it is unlikely the sizes will match...

 ...rather than failing silently.
It might still be useful for generic code, so a compiler warning would probably not be suitable. However, it might be a good idea for a linter such as Dscanner, which, unlike the compiler, sees types as they are written in the code, not as they are calculated through metaprogramming.
Sep 23 2019
parent reply Brett <Brett gmail.com> writes:
On Tuesday, 24 September 2019 at 00:29:05 UTC, Vladimir Panteleev 
wrote:
 On Monday, 23 September 2019 at 23:22:14 UTC, Brett wrote:
 I guess you are probably right... I was thinking that it would 
 compare up to a null terminator. Seems kinda buggy... maybe 
 the compiler needs to give a warning? After all, compared a 
 fixed size array with a dynamic array then will almost always 
 fail since it is unlikely the sizes will match...

 ...rather than failing silently.
It might still be useful for generic code, so a compiler warning would probably not be suitable. However, it might be a good idea for a linter such as Dscanner, which, unlike the compiler, sees types as they are written in the code, not as they are calculated through metaprogramming.
The only issue is that buggy dynamic code can result if someone compares the two and it will fail silently. It could be quite complex bug that destroys the space station. Warnings never hurt and with the ability to disable specific ones one can bypass such issues. (disable then enable) But if it behaves in a non-standard way based on some somewhat arbitrary limitation(fixed arrays are only arbitrary because of the limitations of computers) then it's going to bit people and the more D is used the more people that will get bitten. If I convert a static array to a string, I want the "string" portion of the array. Strings are special, they are meant to have specific representation. Strings do not have 0 characters in them normally. So upon conversion, to!string would detect this and either error out or stop the conversion at that point. The only time one would want to retain junk values is for displaying bytes, but then one should just convert to a byte or char array. But of course those people that have be using to!string to convert arbitrary bytes will have their code broken... but I imagine few have done this(there really is no point). The same thing should happen when converting anything to a string, it should detect malformed strings and either error or terminate(if zero terminated). This makes for a more consistent ecosystem. if, for example, I stick null terminated strings in a buffer then to!string will automatically recover them(the first one, assuming one each time). There is probably no win-win situation though and so I suggest just a warning when converting arrays to strings.
Sep 24 2019
parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Tuesday, 24 September 2019 at 21:40:47 UTC, Brett wrote:
 The only issue is that buggy dynamic code can result if someone 
 compares the two and it will fail silently.
But, you don't know if the static array actually contains a null-terminated string (in which case the comparison is a bug) or an actual meaningful string of that length, such as a string literal represented as a static array (in which case the comparison is completely valid).
 It could be quite complex bug that destroys the space station.
The worst kind of bugs are the ones for which the program works correctly 99.9% of the time (including in all unit tests), but 0.1% of the time things explode. This doesn't seem to me like that kind of a bug, if only that a NUL character will always be presented in a zero-terminated string embedded in a static array, but practically never in a D string.
 If I convert a static array to a string, I want the "string" 
 portion of the array.
Zero-terminated strings are kind of a C thing. D isn't C, it has its own string type. Even though many libraries use a C ABI for interop, and thus use C strings, this isn't a requirement for a D program - after all, you can write your own kernel and operating system in D, all fully without zero-terminated strings.
Sep 24 2019