Bug 832 – NRVO: return inside foreach results in junk
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Linux
Creation time
2007-01-12T04:36:00Z
Last change time
2014-02-15T13:13:34Z
Keywords
wrong-code
Assigned to
bugzilla
Creator
alan
Comments
Comment #0 by alan — 2007-01-12T04:36:30Z
The behaviour changed in dmd-0.178 such that foreach on an array of structs only appears to do a shallow copy, rather than a deep copy.
output of the code below is 29/30 or <.178, and a random number on 178/1.0.
import std.stdio;
const char[] XML_PUBLIC_ID_SYNCML_SYNCML11 ="-//SYNCML//DTD SyncML 1.1//EN";
struct WBXMLPublicIDEntry {
int wbxmlPublicID; /**< WBXML Public ID */
char[] xmlPublicID; /**< XML Public ID */
char[] xmlRootElt; /**< XML Root Element */
char[] xmlDTD; /**< XML DTD */
}
const WBXMLPublicIDEntry sv_wml11_public_id = {
33,
XML_PUBLIC_ID_SYNCML_SYNCML11,
"wml",
"http://www.wapforum.org/DTD/wml.xml"
};
struct WBXMLLangEntry
{
int langID; /**< Language ID */
WBXMLPublicIDEntry publicID; /**< Public ID */
}
const WBXMLLangEntry mainTable[] = [
{ 123,
sv_wml11_public_id },
{ 132, sv_wml11_public_id }
];
void main()
{
WBXMLLangEntry mt = getfirst();
WBXMLPublicIDEntry pie = getName(mt);
writefln("got %d", pie.xmlPublicID.length);
}
static WBXMLLangEntry getfirst()
{
foreach(mt;mainTable) {
return mt;
}
}
WBXMLPublicIDEntry getName(WBXMLLangEntry mt)
{
return mt.publicID;
}
> What |Removed |Added
> ----------------------------------------------------------------------------
> Summary|Struct copying changed in |Struct copying changed in
> |1.0 |1.0
Find the differences.. :S
Comment #3 by lio+bugzilla — 2007-01-27T04:03:13Z
// Smaller program with same problem.
// Should print "1" three times, but only first is OK
import std.stdio;
struct Struct
{
int langID;
long _force_nrvo;
}
Struct[1] table;
Struct getfirst()
{
foreach(v; table) { //inout also doesn't work
writefln(v.langID);// not OK
return v;
}
}
void main()
{
table[0].langID = 1;
foreach(v; table) {
writefln(v.langID);//OK
break;
}
auto v = getfirst();
writefln(v.langID);// not OK
}
Comment #4 by alan — 2007-01-31T03:49:28Z
For reference, the workaround is to return pointers to the struct, rather than passing around the Struct.