¿Por qué esta obvia recursión infinita no da una advertencia al comstackdor?

Hace muchos meses, tuve que arreglar algunos códigos que causaron algunos problemas. El código se veía básicamente así:

int badFun() { return badFun(); }

Obviamente, esto provocó un desbordamiento de stack incluso en el lenguaje de alto nivel con el que estaba trabajando (4Test in SilkTest). No hay forma de que este código pueda ser visto como beneficioso. El primer signo de problemas fueron las advertencias que se vieron después de que el script terminó, pero no los errores de comstackción o las advertencias. Curiosamente, intenté escribir progtwigs en C ++, C # y Python con la misma estructura, y todos ellos fueron comstackdos / interpretados sin errores de syntax o advertencias, incluso aunque hubo errores de tiempo de ejecución en todos los casos. Ni siquiera vi ninguna advertencia en ninguno de estos casos. ¿Por qué no se ve esto como un posible problema por defecto?

EDITAR: Intenté escribir el equivalente de esa función en los tres idiomas, así que agregué esas tags de función. Estoy más interesado en las razones generales por las que el código como este se realiza sin advertencias. Por favor, vuelva a etiquetar si es necesario.

Aquí está el trato: las advertencias del comstackdor son características . Las características requieren esfuerzo , y el esfuerzo es una cantidad finita. (Puede medirse en dólares o puede medirse en el número de horas que alguien está dispuesto a dedicar a un proyecto de código abierto, pero le aseguro que es finito).

Por lo tanto tenemos que presupuestar ese esfuerzo. Cada hora que dedicamos a diseñar, implementar, probar y depurar una característica es una hora que podríamos haber pasado haciendo otra cosa. Por lo tanto, tenemos mucho cuidado al decidir qué características agregar.

Eso es verdad de todas las características. Las advertencias tienen preocupaciones adicionales especiales. Una advertencia debe ser sobre el código que tiene las siguientes características:

  • Legal. Obviamente el código tiene que ser legal; si no es legal, entonces no es una advertencia en primer lugar, es un error.
  • Casi sin duda mal. Una advertencia que le advierte sobre el código correcto y deseable es una mala advertencia. (Además, si el código es correcto, debería haber una manera de escribir el código de manera que la advertencia desaparezca).
  • Inobjective Las advertencias deben informarle sobre los errores que son sutiles, en lugar de obvios.
  • Amparable al análisis. Algunas advertencias son simplemente imposibles; una advertencia que requiere que el comstackdor resuelva El problema de la detención, por ejemplo, no va a suceder ya que eso es imposible.
  • Es poco probable que sea atrapado por otras formas de prueba.

En su ejemplo específico, vemos que se cumplen algunas de estas condiciones. El código es legal, y casi seguro que es incorrecto. ¿Pero es inobjective? Alguien puede mirar fácilmente el código y ver que es una recursión infinita; La advertencia no ayuda mucho. ¿Es susceptible de análisis? El ejemplo trivial que da es, pero el problema general de encontrar recursiones ilimitadas es equivalente a resolver el problema de la detención. ¿Es poco probable que sea atrapado por otras formas de prueba? No. En el momento en que ejecute ese código en su caso de prueba, recibirá una excepción que le informará con precisión qué es lo que está mal.

Por lo tanto, no vale la pena hacer ese aviso. Hay mejores maneras en que podríamos gastar ese presupuesto.

¿Por qué esto no es visto como un problema por defecto?

El error es un error de tiempo de ejecución, no un error de tiempo de comstackción. El código es perfectamente válido, simplemente hace algo estúpido. El caso muy simple que usted muestra podría ser detectado, pero sería difícil detectar muchos casos que serían solo un poco más complicados:

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

Para determinar si eso es un problema, el comstackdor debe tratar de averiguar si la condición siempre será verdadera o no. En el caso general, no creo que esto sea más computable que determinar si el progtwig finalmente se detendrá (es decir, es probable que no sea computable ).

Ningún comstackdor de ningún lenguaje de progtwigción tiene ningún tipo de idea acerca de la semántica del código que comstack. Este es un código válido, aunque estúpido, por lo que será comstackdo.

¿Cómo se supone que el comstackdor o intérprete sabe qué está haciendo la función? El scope del comstackdor y el intérprete es comstackr o interpretar el código sintáctico, no interpretar la semántica de su código.

Incluso si un comstackdor comprobara esto, ¿dónde trazas la línea? ¿Qué pasaría si tuvieras una función recursiva que calculara factorial para siempre?

Porque el comstackdor no verificará este tipo de cosas.

Si instala un analizador de código como Resharper en Visual Studio , aparecerá una advertencia de llamada recursiva infinita o algo así en caso de que haya habilitado la opción de análisis de código.

Dudo que el comstackdor pueda detectar un fenómeno de tiempo de ejecución (desbordamiento de stack) en tiempo de comstackción. Hay muchos casos válidos para llamar a una función dentro de sí, recursión. Pero, ¿cómo puede el comstackdor saber lo bueno de los malos casos de recursión?

A menos que tenga algo de inteligencia artificial añadida, no creo que un comstackdor pueda detectar las diferencias entre una recursión buena y una mala, ese es el trabajo de un progtwigdor.

Como usted ha mencionado, el comstackdor simplemente comprueba los errores sintéticos. La función recursiva es perfectamente válida sin ningún error.

Durante el tiempo de ejecución,

cuando se desborda la stack, se produce un error debido a un desbordamiento de stack * no a causa del código *.

La función recursiva es completamente válida, pero nuevamente en la implementación debemos poner la verificación de condición para devolver los valores antes de que se llene la stack.