6

Digamos que tengo una función simple como esto:operadores en cortocircuito y la recursión de cola

int all_true(int* bools, int len) { 
    if (len < 1) return TRUE; 
    return *bools && all_true(bools+1, len-1); 
} 

Esta función se puede escribir en un estilo más obviamente recursiva de cola de la siguiente manera:

int all_true(int* bools, int len) { 
    if (len < 1) return TRUE; 
    if (!*bools) return FALSE; 
    return all_true(bools+1, len-1); 
} 

Lógicamente, hay una diferencia cero entre los dos; suponiendo que bools contiene solo TRUE o FALSE (definidos de forma sensata), hacen exactamente lo mismo.

Mi pregunta es: si un compilador es suficientemente inteligente para optimizar el segundo como una llamada recursiva de cola, es razonable esperar que para optimizar el primero de la misma manera, teniendo en cuenta que "& &" cortocircuitos? Obviamente, si se usara un operador sin cortocircuito, esto sería no recursivo de cola porque ambas expresiones se evaluarían antes de que el operador se aplique, pero tengo curiosidad sobre el caso de cortocircuito.

(Antes de recibir una avalancha de comentarios que me dicen que los compiladores de C generalmente no optimizan las llamadas recursivas de cola: considere esta una pregunta general sobre la optimización de llamadas recursivas de cola con operadores de cortocircuito, independientemente del idioma. Estaré encantado de reescribir esto en Scheme, Haskell, OCaml, F #, Python, o qué diablos más si no entiendes C.)

+0

gcc optimiza las llamadas recursivas. – Arafangion

Respuesta

2

Tu pregunta es realmente "qué tan inteligente es el compilador ? " pero no indica qué compilador está utilizando.

Dado un compilador razonable hipotético que convierte el código fuente a un gráfico de flujo de intermediario antes de optimizaciones, ambos fragmentos de código que ha escrito podría ser representado de la misma manera (el operador & &, mientras que es conveniente para escribir, no es casi tan trivialmente compilado como el operador &, así que no me sorprendería si se expande en una fase en un compilador hipotético). En ese supuesto, es razonable afirmar que la respuesta a su pregunta es "sí".

Sin embargo, si realmente vas a confiar en esto, solo debes probarlo con el compilador que estés usando.

Cuestiones relacionadas