On Monday, 22 July 2013 at 15:51:45 UTC, monarch_dodra wrote:
So... you are saying that if the grammar allows it, then the
behavior is specified?
You may argue that although grammar does allows it, the feature
is semantically not defined. However here it is known what "ref
int i" means, to be more precise what you can do with objects
marked with ref attribute.
All I see, is you iterating over references to the elements of
an aggregate. The final behavior really depends on how said
aggregate is implemented. If anything, if the behavior *was*
defined, then I'd simply argue the behavior is wrong: I don't
see why changing the values of the elements of the aggregate
should change the amount of elements you iterate on at all.
Also:
//----
int[] x = [1, 2, 3, 4, 5];
foreach (ref i; iota(0, 5))
{
writeln(x[i]);
++i;
}
//----
This also compiles, but I used a different aggregate, yet
represents the same thing. Because it is implemented
differently, I get a completely different result. Unless I'm
mistaken, when a result depends on the implementation, and the
implementation doesn't state what the result is, then that's
what unspecified behavior is. (unspecified, not undefined).
This is different because in 0..5 ref int maps directly to
variable modified, but in iota() it maps to value returned by
.front property function and since it doesn't return by ref,
refness is wiped out. Behavior is defined in both cases.
This is an example of unspecified behavior:
<...>
What is "__limit1631" ? Doesn't compile for me.
This one may http://dpaste.dzfl.pl/3faf27ba
extern(C) int printf (const char*, ...);
void main()
{
int[] x = [1, 2, 3, 4, 5];
foreach (ref i; 0 .. 5)
{
__limit6--; // or 5 depending on dmd version
printf("%d\n", x[i]);
}
}
1
2
3
This is example of unspecified behavior (better undefined) due to
playing with __identifiers and how dmd bug can make D code looks
strange.