Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this obvious infinite recursion give a compiler warning? [closed]

Many months back, I had to fix up some code that caused some problems. The code looked basically like this:

int badFun() { return badFun(); }

This obviously caused a stack overflow even in the high level language I was working with (4Test in SilkTest). There's no way this code could be seen as beneficial. The first sign of problems were warnings seen after the script finished, but no compile errors or warnings. Curiously, I tried writing programs in C++, C# and Python with the same structure, and all of them compiled/interpreted with no syntax errors or warnings, even through there were runtime errors in all cases. I didn't even see any warnings in any of these cases. Why isn't this seen as a possible problem by default?

EDIT: I tried writing the equivalent of that function in all three languages, so I added those function tags. I'm more interested in overall reasons why code like this gets through with no warnings. Please retag if necessary.

like image 690
joshin4colours Avatar asked Jan 06 '12 17:01

joshin4colours


4 Answers

Here's the deal: compiler warnings are features. Features require effort, and effort is a finite quantity. (It might be measured in dollars or it might be measured in the number of hours someone is willing to give to an open source project, but I assure you, it is finite.)

Therefore we have to budget that effort. Every hour we spend designing, implementing, testing and debugging a feature is an hour we could have spent doing something else. Therefore we are very careful about deciding what features to add.

That's true of all features. Warnings have special additional concerns. A warning has to be about code that has the following characteristics:

  • Legal. Obviously the code has to be legal; if it is not legal then its not a warning in the first place, its an error.
  • Almost certainly wrong. A warning that warns you about correct, desirable code is a bad warning. (Also, if the code is correct, there should be a way to write the code such that the warning goes away.)
  • Inobvious. Warnings should tell you about mistakes that are subtle, rather than obvious.
  • Amenable to analysis. Some warnings are simply impossible; a warning that requires the compiler to solve The Halting Problem for example, is not going to happen since that is impossible.
  • Unlikely to be caught by other forms of testing.

In your specific example, we see that some of these conditions are met. The code is legal, and almost certainly wrong. But is it inobvious? Someone can easily look at the code and see that it is an infinite recursion; the warning does not help much. Is it amenable to analysis? The trivial example you give is, but the general problem of finding unbounded recursions is equivalent to solving the halting problem. Is it unlikely to be caught by other forms of testing? No. The moment you run that code in your test case, you're going to get an exception telling you precisely what is wrong.

Thus, it is not worth our while to make that warning. There are better ways we could be spending that budget.

like image 176
Eric Lippert Avatar answered Nov 09 '22 11:11

Eric Lippert


Why isn't this seen as problem by default?

The error is a run time error, not a compile time error. The code is perfectly valid, it just does something stupid. The very simple case that you show could certainly be detected, but many cases that would be only slightly more complicated would be difficult to detect:

void evil() {
    if (somethingThatTurnsOutToAlwaysBeTrue)
        evil();
}

In order to determine whether that's a problem, the compiler has to try to figure out whether the condition will always be true or not. In the general case, I don't think this is any more computable than determining whether the program will eventually stop (i.e. it's provably not computable).

like image 24
Caleb Avatar answered Nov 09 '22 13:11

Caleb


No compiler of any programming language has any sort of idea about the semantics of the code it compiles. This is valid code, though stupid, so it will be compiled.

like image 3
Mithrandir Avatar answered Nov 09 '22 13:11

Mithrandir


How is the compiler or interpreter suppose to know what the function is doing? The scope of the compiler and interpreter is to compile or interpret the syntactical code-- not interpret the semantics of your code.

Even if a compiler did check for this, where do you draw the line? What if you had a recursive function that calculated factorial forever?

like image 2
Donald Miner Avatar answered Nov 09 '22 11:11

Donald Miner