¿Siempre se realiza un incremento posterior antes de una llamada de función?

2 minutos de lectura

Avatar de usuario de 12431234123412341234123
12431234123412341234123

Considere este código:

#include <stdio.h>
static int g=3;

static int foo(int a)
{ 
  return g+a; 
}

int main(void)
{
  printf("%i\n",foo(g++));
}

¿La salida es siempre 7 (suponiendo que printf() no fallará)? Es decir, ¿la norma garantiza que la expresión g++dentro de la lista de argumentos para foo()se ejecuta antes foo() ¿es ingresado? ¿O es posible que el compilador establezca g=3 llamadas foo() con g==3 e incrementar g después de la ejecución de foo() está hecho (y las salidas 6 en lugar de 7)?

Todo el compilador (versiones) que pruebo imprime 7 y no mostró ninguna advertencia. Pero eso no significa que tenga que ser así.

  • La expresion foo(g++) es algo equivalente a int old_value = g; g += 1; foo(old_value);. Eso está garantizado por la especificación. Si desea respuestas con citas de la especificación, agregue el language-lawyer etiqueta. De lo contrario esta referencia de orden de evaluación podría ser una lectura útil (aunque un poco difícil).

    – Un tipo programador

    15 de junio a las 11:14

  • @jarmod Microsoft podría no ser la mejor referencia para la pregunta etiquetada por un abogado de idiomas, considerando el historial con su compilador de C.

    – usuario694733

    15 de junio a las 11:33

  • @ user694733 ah, comentario justo. Veo que la etiqueta de abogado de idioma se agregó en algún momento después de que se hizo la pregunta.

    – jarmod

    15 de junio a las 11:41

avatar de usuario de nielsen
nielsen

como se indica aquí:

  1. Hay un punto de secuencia después de la evaluación de todos los argumentos de función y del designador de función, y antes de la llamada de función real.

Esto garantiza que g++ se completa, incluido el incremento g antes de llamar a la función.

Entonces, sí, el resultado. 7 está garantizado y bien definido.

Actualizar: El estándar C17 establece esto directamente en la primera oración de §6.5.2.2-10:

Hay un punto de secuencia después de las evaluaciones del designador de función y los argumentos reales, pero antes de la llamada real. Cada evaluación en la función de llamada (incluidas otras llamadas de función) que no esté secuenciada específicamente antes o después de la ejecución del cuerpo de la función llamada tiene una secuencia indeterminada con respecto a la ejecución de la función llamada.

  • Puede valer la pena señalar, aunque no es relevante para la pregunta en particular, que una operación que tiene una “secuencia indeterminada” con respecto a la ejecución de la función llamada se secuenciará completamente antes de la ejecución de la función o completamente después.

    – Super gato

    15 de junio a las 19:24

¿Ha sido útil esta solución?