On Monday, 22 July 2013 at 15:39:11 UTC, Maxim Fomin wrote:
On Monday, 22 July 2013 at 15:04:25 UTC, monarch_dodra wrote:
On Monday, 22 July 2013 at 12:51:31 UTC, Andrej Mitrovic wrote:
On 7/22/13, JS <js.m...@gmail.com> wrote:
foreach doesn't allow you to modify the index to skip over
elements.
It does:
-----
import std.stdio;
void main()
{
int[] x = [1, 2, 3, 4, 5];
foreach (ref i; 0 .. 5)
{
writeln(x[i]);
++i;
}
}
-----
Writes:
1
3
5
99% sure that's unspecified behavior. I wouldn't rely on
anything like that.
Of course it is specified behavior.
ForeachStatement:
Foreach (ForeachTypeList ; Aggregate)
NoScopeNonEmptyStatement
Foreach:
foreach
foreach_reverse
ForeachTypeList:
ForeachType
ForeachType , ForeachTypeList
ForeachType:
refopt BasicType Declarator
refopt Identifier
Aggregate:
Expression
So... you are saying that if the grammar allows it, then the
behavior is specified?
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 an example of unspecified behavior:
import std.stdio;
void main()
{
int[] x = [1, 2, 3, 4, 5];
foreach (ref i; 0 .. 5)
{
__limit1631--;
writeln(x[i]);
}
}
What is "__limit1631" ? Doesn't compile for me.