Bug 2934 – "".dup does not return empty string

Status
REOPENED
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Linux
Creation time
2009-05-04T09:02:10Z
Last change time
2024-12-13T17:49:57Z
Assigned to
No Owner
Creator
Qian Xu
Moved to GitHub: dmd#17977 →

Comments

Comment #0 by qian.xu — 2009-05-04T09:02:10Z
The following code will throw an exception: char[] s; assert( s.dup is null); // OK assert("".dup !is null); // FAILED "".dup is expectly also an empty string. Confirmed with dmd v1, gdc
Comment #1 by qian.xu — 2009-05-04T09:25:06Z
Sorry. I should have post the following code: char[] s; assert(s is null); assert(s.dup is null); assert("" !is null); // OK assert("".dup !is null); // FAILED The last two lines behave not consistent. Either both are failed, or both are passed.
Comment #2 by schveiguy — 2009-05-04T12:45:05Z
From posts in the newsgroup, I've determined that this bug is invalid: 1. Duplicating an empty array should always return a null array. Otherwise, you'd have to allocate space to store 0 data bytes in order for the result to be non-null. 2. String literals have a null character implicitly appended to them by the compiler. This is done to ease calling c functions. So a string literal's pointer cannot be null, since it has to point to a static zero byte. The spec identifies specifically item 2 here: http://www.digitalmars.com/d/1.0/arrays.html#strings see the section describing "C's printf and Strings" I could not find a reference for item 1, but I remember reading something about it. Regardless of it is identified specifically in the spec or not, it is not a bug, as the alternative would be to allocate blocks for 0-sized arrays.
Comment #3 by qian.xu — 2009-05-05T02:46:07Z
> 2. String literals have a null character implicitly appended to them by the > compiler. This is done to ease calling c functions. So a string literal's > pointer cannot be null, since it has to point to a static zero byte. I am fully agree with you. But before using ".dup" a string variable has triple-state (null, empty or not empty). After adding a ".dup" to an empty string, it might be reduced to two. This will break existing code, if defensive copies of strings are made. An example is as follows: class test { private char[] val; char[] getVal() { return val.dup; // make a defensive copy to avoid unexpected change from outside } void setVal(char[] val) { this.val = val.dup; } } myTestObj.setVal(""); char[] s = myTestObj.getVal; if (s is null) { // do task 1 } else if (s == "") { // do task 2 } else { // do task 3 } In this case, task 2 is expected to be performed. However task 1 will be performed. > Regardless of it is identified specifically in the spec or not, it is not > a bug, as the alternative would be to allocate blocks for 0-sized arrays. Did you mean, that this is a feature request? I would like to regard the inconsistency of the dup-effect as a defect.
Comment #4 by schveiguy — 2009-05-05T08:48:21Z
From that point of view, your request makes a lot more sense. But there are two counter arguments: 1. Comparing an array to null has limited utility, I don't think it should be in widespread use, as most of the time you only care if the array is empty or not. There may be special cases, but in those cases, you can use arr.ptr == null. It would have been much better if arr == null never compiled. 2. Duping an empty array has limited defensive utility. You can just as easily return the array itself. If it weren't for the horrendous append behavior, it would be a no brainer: T[] edup(T)(T[] arr) { return arr.length == 0 ? arr : arr.dup; } usage: return arr.edup(); Allocating data for duping an empty array is not an acceptable pessimization. However, I thought of another possible solution: A dup of an empty, non-null array can return a pointer into the read only data segment. This would allow a non-allocation on duping an empty array, would not return a pointer to null, and would not accidentally overwrite the original array if appending is done. So a fix can be done.
Comment #5 by robert.schadek — 2024-12-13T17:49:57Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17977 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB