www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Musings on infinite loops and not reachable returns

reply "bearophile" <bearophileHUGS lycos.com> writes:
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
Mar 25 2014
next sibling parent reply "Chris Williams" <yoreanon-chrisw yahoo.co.jp> writes:
On Tuesday, 25 March 2014 at 20:49:57 UTC, bearophile wrote:
 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.
I'm not seeing it. "while (true)" is no more an infinite loop than "for (i = 0; i < x; i++)", if the body of the while has a break or return statement. int i = 0; while (true) { if (i < x) break; i++; }
Mar 25 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Chris Williams:

 I'm not seeing it. "while (true)" is no more an infinite loop 
 than "for (i = 0; i < x; i++)", if the body of the while has a 
 break or return statement.
I see, so there's nothing to improve here :-) Bye, bearophile
Mar 25 2014
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
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.
Mar 25 2014
prev sibling parent reply "anonymous" <anonymous example.com> writes:
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.
(It's not an infinite loop, but the return is dead code.) When you know that it won't be reached, you can (should?) put assert(false) instead of a return.
Mar 25 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
anonymous:

 When you know that it won't be reached, you can (should?) put
 assert(false) instead of a return.
Yes, right, I use assert(false) in those cases :-) Bye, bearophile
Mar 25 2014