Valor de retorno int implícito de la función C

Busqué en Google y parece que no puedo encontrar la respuesta a esta simple pregunta.

Trabajando en una base de código heredada (portada a Linux recientemente, y actualizando lentamente a un nuevo comstackdor) y veo una gran cantidad de

int myfunction(...) { // no return... } 

Sé que el retorno implícito TYPE de una función es int, pero ¿cuál es el retorno implícito? VALUE cuando no se especifica return. He probado y obtenido 0, pero eso es solo con gcc. ¿Es este comstackdor específico o está definido como estándar a 0?

EDITAR: 12/2017 Respuesta aceptada ajustada basada en una referencia a una versión más reciente del estándar.

Tal cosa es posible, pero solo bajo el supuesto de que nunca se usa el valor de retorno de la función. El estándar C11 dice en el párrafo 6.9.1:

Si se alcanza el} que termina una función y el llamador usa el valor de la llamada de función, el comportamiento no está definido.

(La versión anterior de AFAIR tenía una redacción similar)

Por lo tanto, sería una buena idea para transformar todas las funciones de ese tipo que tiene que void funciones, por lo que ningún usuario de dicha función podría tener la tentación de utilizar el valor de retorno.

Del estándar ’89 según se cita en el nuevo testamento:

Fluir fuera del final de una función es equivalente a un retorno sin expresión. En cualquier caso, el valor de retorno no está definido.

Esa norma generalmente expresa el comportamiento sobre el terreno de las implementaciones preexistentes.

Eso es simplemente un comportamiento indefinido; si no rellena el área de retorno (que, por ejemplo, generalmente es eax / rax en procesadores familiares x86 ), tendrá el último valor establecido mediante algún efecto secundario en su función.

Consulte ¿Es obligatoria una statement de devolución para las funciones de C ++ que no devuelven el vacío? que es básicamente un duplicado de esta pregunta (excepto que está etiquetado como C ++).

La statement de devolución nunca es obligatoria al final de una función, incluso si el tipo de devolución de función no es void . No se requiere diagnóstico y no es un comportamiento indefinido.

Ejemplo (comportamiento definido):

 int foo(void) { } int main() { foo(); } 

Pero leer el valor de retorno de foo es un comportamiento indefinido:

 int bla = foo(); // undefined behavior 

Del estándar C:

(C99, 6.9.1p12) “Si el} que termina una función se alcanza, y el valor de la llamada de función es utilizada por la persona que llama, el comportamiento no está definido”.

La función main es una excepción a esta regla, ya que si se llega a } en main , es equivalente a un return 0; statement.

Si las declaraciones return no devuelven un valor, la función se convierte mejor y se declara como, volviendo void :

 void myfunction(...) { ... return; ... } 

Si hay alguna return expr; y algunos return; declaraciones en la función, entonces necesita decidir cuál es el mejor comportamiento y hacer que sean coherentes; siempre devuelve un valor y deja el tipo como int o nunca devuelve un valor y cambia el tipo a void .

Tenga en cuenta que deberá declarar funciones modificadas para devolver el void (en un encabezado, a menos que estén, o deberían estar, static y ocultas en un solo archivo fuente) ya que el tipo de retorno predeterminado (tipo de retorno supuesto) de int ya no es válido.

Puede ser siempre cero en esa función, pero en la mayoría de las architectures (ciertamente x86), la statement de retorno mueve el contenido de un registro específico a un lugar específico en la stack que la persona que llama recuperará y usará como su función de retorno.

La statement de retorno colocará la variable que se le pasó en esa ubicación para que tenga un valor diferente. Mi experiencia al no colocar una statement de devolución específica es que es bastante aleatorio lo que se devuelve y no se puede confiar en que sea lo mismo.

Estoy seguro de que es un comportamiento indefinido para una función cuyo tipo de devolución no es void omitir una statement de return . En C99 hay una excepción para main , donde si se omite la instrucción return , se supone que devuelve 0 implícitamente, pero esto no se aplica a ninguna otra función.

Puede funcionar en una combinación de plataforma / comstackdor específica, pero nunca debe confiar en tales detalles. Usar cualquier tipo de comportamiento indefinido en tu código lo hace inportable. Sin embargo, es común ver un comportamiento indefinido en el código heredado.