Respondiendo porque todas las respuestas existentes dicen que es un comportamiento indefinido, lo cual no es cierto, así que no tengo nada que pueda votar.
En C89 (gracias a pmg por la referencia a un proyecto de norma), 5.1.2.2.3:
Un retorno desde la llamada inicial a la función principal es equivalente a llamar a la función de salida con el valor devuelto por la función principal como argumento. Si se alcanza el }que finaliza la función principal, no se especifica el estado de terminación devuelto al entorno host.
En C99, citando de n1256, 5.1.2.2.3:
Si el tipo de retorno de la función principal es un tipo compatible dentro de t, un retorno de la llamada inicial a la función principal es equivalente a llamar a la función de salida con el valor devuelto por la función principal como su argumento; alcanzar el } que finaliza la función principal devuelve un valor de 0. Si el tipo de retorno no es compatible con int, el estado de terminación devuelto al entorno del host no se especifica.
Entonces, no es un "comportamiento indefinido":se comporta como si el main
la función devuelve, pero en C89 el valor devuelto no está especificado por el estándar. Para su programa de ejemplo, en su implementación, el valor devuelto parece ser consistentemente 12, presumiblemente por la razón que dice Ben Voigt. Dado que está en Linux, probablemente no sea un gran cambio compilar su código como C99 (o de todos modos, compilarlo usando el modo C99 casi compatible de gcc).
Para cualquier función que devuelva un valor, que no sea main
, es es comportamiento indefinido, a menos que la persona que llama no utiliza el valor de retorno (n1256, 6.9.1/12):
Si se alcanza el } que finaliza una función y el autor de la llamada utiliza el valor de la llamada a la función, el comportamiento no está definido.
No estoy seguro si la llamada inicial a main
deben mencionarse como excluidos de esta regla general. No necesita serlo:desde el punto de vista del estándar, esa llamada no tiene una persona que llama, por lo que creo que el valor de la llamada de función no es "utilizado por la persona que llama", aunque se convierte en el estado de terminación. para el programa.
Como dice swegi, es un comportamiento indefinido. Como dicen Steve Jessop et al, es un valor no especificado hasta C89 y especificado en C99 (el comportamiento observado no se ajusta a C99)
Lo que realmente sucede en la mayoría de los entornos es que el valor de retorno de los últimos printf
se deja en el registro utilizado para los valores de retorno.
Entonces será 11 para n ==0, 12 si n es de un dígito, 14 para n de dos dígitos, 16 para n de tres dígitos, etc.