I'm not sure if this is a legitimate bug or one of my brainfarts.
I know that if I'm using a foreach loop with a char array as a reusable
datatype I definitely have to create a copy if I want to store it to a string.
But this code is a little more subtle, check it out (This is Windows only
because it uses the registry, sorry):
module mymodule;
import std.stdio : writeln, write;
import std.windows.registry;
void main()
{
Key HKLM = Registry.localMachine;
Key SFW = HKLM.getKey("software");
string[] names;
foreach (Key key; SFW.keys())
{
string name = key.name();
// string name = key.name().idup; // workaround for the issue
names ~= name;
}
writeln("results:");
foreach (name; names)
{
write(name, ", ");
}
}
The results are quite unexpected. The strings get overwritten with each other,
and in my case the results are similar to this:
Sun Microsystems, Sun Micros, Sun , Sun Micr, Sun, Sun Mic,...
And it goes like that for a hundred or so values, then switches to the next
name and writes more garbage like that.
If I use .idup, the problem goes away. What I don't understand is why assigning
a string to a string isn't safe in this case? They're both immutable, so I was
expecting the contents of the strings never to change.
If it's not a bug, it certainly is a subtle issue. The original foreach loop
was quite big, and it took some time to figure out the problem. Are we *always*
supossed to be using .idup in a foreach loop? Of course, the Key key variable
is reused in the foreach loop, so I guess this has something to do with the
results.