On Tuesday, 25 March 2014 at 20:49:57 UTC, bearophile wrote:
This code compiles with no errors or warnings:
struct Foo {
int opApply(int delegate(ref ubyte) dg) {
int result;
ubyte x;
while (true) {
result = dg(x);
if (result) return result;
x++;
}
//return result; // Warning: statement is not reachable
}
}
struct Bar {
int opApply(int delegate(ref ubyte) dg) {
int result;
foreach (y; Foo()) {
result = dg(y);
if (result) return result;
}
return result; // required
}
}
void main() {}
Note how the opApply() of Foo should not end with a return,
while the opApply() of Bar is required by the D compiler to end
with a return.
Yet, Foo is contains an infinite loop, so the result of Bar
will not be reached. But the type system of D is not strong
enough to see that.
There are languages able to specify such things in their type
system. But it's probably not worth adding this to the D type
system (on the other hand some people have suggested to add a
@noreturn annotation to D, that's usable to denote functions
that never return).
Bye,
bearophile
To be honest, "statement not reachable" is a *bane* in generic
code. I wish it didn't trigger in parameterized code.
Imagine this trivial case:
//----
for ( ; !r.empty ; r.popFront() )
if (e == 5)
return 5;
return 0;
//----
To get this to compile with all range types, including finite,
infinite, and (god forbid) statically empty ranges, is a HUGE
pain.
BTW:
return result; // required
Use "assert(0)" instead.