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

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

int badFun() { return badFun(); }

This clearly caused a stack overflow even in the high-level language I worked with (4Test in SilkTest). There is no way that this code can be considered useful. The first signs of problems were warnings after the script was completed, but not compilation errors or warnings. Curiously, I tried to write programs in C ++, C # and Python with the same structure, and all of them were compiled / interpreted without syntax errors or warnings, even despite runtime errors in all cases. In any of these cases, I did not even see any warnings. Why is this problem not considered a possible problem by default?

EDIT: I tried to write the equivalent of this function in all three languages, so I added function tags. I'm more interested in the general reasons why code like this runs without warning. Please try if necessary.

+8
c ++ compiler-construction python c # recursion
Jan 06 '12 at 17:57
source share
7 answers

Here's the deal: compiler warnings are functions. Functions require effort, and effort is a finite amount. (This can be measured in dollars or can be measured in the number of hours that someone wants to pass on to an open source project, but I assure you that this is of course.)

Therefore, we must highlight budgetary efforts. Every hour we carry out the design, implementation, testing and debugging of a function - this is an hour that we could spend on doing something else. Therefore, we are very careful to decide which features to add.

This is true for all functions. Alerts have special additional problems. The warning should be about code that has the following characteristics:

  • Legal. Obviously, the code must be legal; if this is not legal, then this is not a warning, first of all, his mistake.
  • Almost certainly wrong. A warning warning you of the correct, desirable code is a bad warning. (Also, if the code is correct, there must be a way to write the code so that the warning goes away.)
  • Inobvious. Warnings should inform you of errors that are subtle and not obvious.
  • Suitable for analysis. Some warnings are simply not possible; A warning that requires the compiler to solve a stop problem, for example, will not occur, since this is not possible.
  • Other forms of testing are unlikely to be caught.

In your specific example, we see that some of these conditions are met. The code is legal and almost certainly incorrect. But is that obvious? Someone can easily look at the code and see that it is infinite recursion; warning doesn't help much. Is he fit for analysis? The trivial example you give, but the general problem of finding unlimited recursions is equivalent to solving the stop problem. Is it likely that he will be caught by other forms of testing? No. The moment you run this code in a test case, you will get an exception in which you will indicate exactly what is wrong.

Therefore, we should not make this warning. There are better ways we could spend this budget.

+39
Jan 06 '12 at 18:39
source share

Why is this problem not considered by default?

An error is a runtime error, not a compile-time error. The code is completely correct, it just does something stupid. The very simple case that you are showing can be definitely detected, but many cases that would be a little more complicated would be difficult to detect:

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

To determine if this is a problem, the compiler should try to find out if the condition is always true or not. In the general case, I do not think that it is more difficult to calculate than to determine whether the program will eventually be stopped (i.e., it is provably not computable ).

+20
Jan 06 2018-12-18T00:
source share

No compiler of any programming language has an idea of ​​the semantics of the code that it compiles. This is valid code, although stupid, so it will be compiled.

+3
Jan 06 2018-12-18T00:
source share

How should the compiler or interpreter know what the function does? The scope of the compiler and interpreter is to compile or interpret the syntax code - do not interpret the semantics of your code.

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

+2
Jan 06 '12 at 18:03
source share

Because the compiler will not check this stuff.

If you install a code analyzer such as Resharper in Visual Studio , it will issue a warning about an infinite recursive call or sth, as if you enabled the code analysis option.

+1
Jan 6 '12 at 18:01
source share

I doubt that the compiler can detect at compile time events at runtime (stack overflow). There are many valid cases for calling a function within itself, recursion. But how does the compiler know the good of bad recursion cases?

If it does not have AI added, I don’t think that the compiler could detect the differences between good and bad recursion, which is the programmer’s job.

+1
Jan 06 2018-12-18T00:
source share

As you already mentioned, the compiler simply checks for syntax errors. a recursive function is valid without any error.

At runtime,

when the stack is full, it throws an error due to * not because of the code *.

The recursive function is valid, but again in the implementation we need to check the condition for returning values ​​before filling the stack.

0
Jan 06 '12 at 18:08
source share



All Articles