Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - How to create a non-detectable infinite loop?

This is just an "I am Curious" question.

In C#-in-depth Jon Skeet says about lambda expressions:
"if there is a nonvoid return type every code path has to return a compatible value." (Page 233)

The footnote then says:
"Code paths throwing exceptions don't need to return a value, of course, and neither do detectable infinite loops." (Page 233)

I am wondering what constitutes a non-detectable infinite loop?

Can this be done by only logic? or it is done by using external factors like a database or file system?

like image 990
Vaccano Avatar asked Feb 22 '10 18:02

Vaccano


2 Answers

What Jon is referring to is described in section 8.1 of the specification. The compiler can detect only very simple infinite loops, like:

while(true) { if (0 != 0) return 123; }

The compiler is smart enough to see that the return is never reached, and therefore that the loop runs forever. It is legal, though crazy, to say:

int M() { while(true) { } }

because though there is no path which returns an int, there is also no path which returns without returning an int!

The compiler is not smart enough to find other kinds of infinite loops. For example:

int x = 123;
while(true) { if (x * 0 != 0) break; }

This is clearly an infinite loop. But the compiler doesn't know that. The compiler says "well, maybe there is some value of x where x * 0 is not zero, so then the break is reachable, so this isn't an infinite loop". You and I know that this is impossible because we know math, but the compiler does not.

Read section 8.1 if you want the details.

like image 105
Eric Lippert Avatar answered Oct 16 '22 09:10

Eric Lippert


It's pretty trivial to create an infinite loop using external sources, or even abusing tools like interfaces.

For example:

  public interface INumbers
    {
        int GetNumber(int arg);
    }
    public class StaticNumber : INumbers
    {
        public int GetNumber(int arg)
        {
            return 1;
        }
    }
    public void DoStuff(INumbers num)
    {
        int i = 42;
        while ((i = num.GetNumber(i)) != 0)
        {
            ;
        }
    }

and then a simple

Action action = () => DoStuff(new StaticNumber());
like image 40
Tanzelax Avatar answered Oct 16 '22 08:10

Tanzelax