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.
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:
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.
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).
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With