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; }
Comment #1 by wbaxter — 2007-01-12T05:14:47Z
Probably also NRVO-related. See http://d.puremagic.com/issues/show_bug.cgi?id=829 also.
Comment #2 by lio+bugzilla — 2007-01-12T05:30:28Z
> 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.
Comment #5 by lio+bugzilla — 2007-02-09T02:08:19Z
Tested both programs, work OK in 1.005
Comment #6 by bugzilla — 2007-02-12T03:38:45Z
Fixed DMD 1.005
Comment #7 by thomas-dloop — 2007-02-15T03:42:51Z