Bug 12478 – Current element in foreach statement is implicitly casted to const
Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-03-27T00:33:00Z
Last change time
2015-06-04T08:33:36Z
Assigned to
nobody
Creator
neuranuz
Comments
Comment #0 by neuranuz — 2014-03-27T00:33:40Z
When iterating over aggregate with foreach statement current element is imlicitly casted to const although source aggregate is not surely const. The following code illustrates it.
struct S
{ string str;
int num;
}
class C
{
private:
S[] _items;
public:
inout(S)* getItemPtr(string str) inout
{ foreach( ref s; _items )
{
if( s.str == str )
{ auto itemPtr = &s;
pragma(msg, typeof(itemPtr));
//Expected to be inout(s)*. Not inout(const(S))* (in DMD 2.065) or const(S)* (in DMD 2.064)
static assert( is( typeof(itemPtr) == inout(S)* ) );
return itemPtr; //Error: not implicitly convertible to inout(S)*
}
}
return null;
}
}
When using inout method in this case result item pointer can address const or mutable data because result is inout(S)*. But operation &s returns pointer of type inout(const(S))* (in 2.064, or const(S)* in previous versions of DMD). So it points to not mutable data in any case. But it expected to be inout(S)*, because method is inout and *this* reference is inout (and all of it's fields without modifiers). So foreach statement iterating over *inout* array should give us inout reference to data, but not const or inout(const).
Comment #1 by k.hara.pg — 2015-06-04T08:33:36Z
Fixed from 2.066.
*** This issue has been marked as a duplicate of issue 12523 ***