
Bazuca
¿Qué significa el término “declaración implícita de una función”? Una llamada a una función de biblioteca estándar sin incluir el archivo de encabezado apropiado produce una advertencia como en el caso de:
int main(){
printf("How is this not an error?");
return 0;
}
¿No debería ser un error usar una función sin declararla? Por favor explique en detalle. Busqué en este sitio y encontré preguntas similares, pero no pude encontrar una respuesta definitiva. La mayoría de las respuestas dijeron algo sobre incluir el archivo de encabezado para eliminar la advertencia, pero quiero saber cómo esto no es un error.

ugoren
Debe considerarse un error. Pero C es un idioma antiguo, por lo que es solo una advertencia.
Compilando con -Werror
(gcc) soluciona este problema.
Cuando C no encuentra una declaración, asume esta declaración implícita: int f();
, lo que significa que la función puede recibir lo que le des y devuelve un número entero. Si esto sucede lo suficientemente cerca (y en caso de printf
, lo es), entonces las cosas pueden funcionar. En algunos casos (por ejemplo, la función en realidad devuelve un puntero y los punteros son más grandes que los enteros), puede causar problemas reales.
Tenga en cuenta que esto se solucionó en los estándares C más nuevos (C99, C11). En estos estándares, esto es un error. Sin embargo, gcc
no implementa estos estándares de forma predeterminada, por lo que aún recibe la advertencia.
Las declaraciones implícitas no son válidas en C.
C99 eliminó esta función (presente en C89).
gcc
elige emitir solo una advertencia por defecto con -std=c99
pero un compilador tiene derecho a negarse a traducir dicho programa.

Blagovest Büyükliev
Una función declarada implícitamente es aquella que no tiene prototipo ni definición, pero se llama en alguna parte del código. Por eso, el compilador no puede verificar que este sea el uso previsto de la función (si el recuento y el tipo de los argumentos coinciden). La resolución de las referencias a él se realiza después de la compilación, en tiempo de enlace (como con todos los demás símbolos globales), por lo que técnicamente no es un problema omitir el prototipo.
Se supone que el programador sabe lo que hace y esta es la premisa bajo la cual se omite el contrato formal de suministro de un prototipo.
Pueden ocurrir errores desagradables si se llama a la función con argumentos de un tipo o recuento incorrecto. La manifestación más probable de esto es una corrupción de la pila.
Hoy en día, esta característica puede parecer una extraña rareza, pero en los viejos tiempos era una forma de reducir la cantidad de archivos de encabezado incluidos, por lo tanto, una compilación más rápida.

zan lince
Debido a razones históricas que se remontan a la primera versión de C, se supone que las funciones tienen una definición implícita de int function(int arg1, int arg2, int arg3, etc)
.
Edit: no, me equivoqué int
por los argumentos. En su lugar, pasa cualquier tipo de argumento. Así que podría ser un int
o un double
o un char*
. Sin un prototipo, el compilador pasará el tamaño del argumento y será mejor que la función que se llama use el tipo de argumento correcto para recibirlo.
Para más detalles mira hacia arriba K&R C
.
C es un lenguaje de muy bajo nivel, por lo que le permite crear casi cualquier archivo de objeto legal (.o) que pueda concebir. Debería pensar en C como un lenguaje ensamblador básicamente disfrazado.
En particular, C no requiere que se declaren las funciones antes de usarlas. Si llama a una función sin declararla, el uso de la función se convierte en su declaración (implícita). En una prueba simple que acabo de ejecutar, esto es solo una advertencia en el caso de funciones de biblioteca integradas como printf (al menos en GCC), pero para funciones aleatorias, se compilará bien.
Por supuesto, cuando intenta vincular y no puede encontrar foo, obtendrá un error.
En el caso de funciones de biblioteca como printf, algunos compiladores contienen declaraciones integradas para ellos, de modo que pueden realizar una verificación de tipo básica, de modo que cuando la declaración implícita (del uso) no coincida con la declaración integrada, recibir una advertencia.
La biblioteca C estándar está vinculada de forma predeterminada a las compilaciones; por ejemplo, con gcc tiene que pasar explícitamente -nostdlib como argumento a la compilación para obligarla a no vincularse con libc.
– bert
7 febrero 2012 a las 19:50
@tbert Es por eso que el enlazador no se queja, pero el enlazador tiene un efecto muy pequeño en lo que hace el compilador con el código C.
– usuario395760
7 febrero 2012 a las 19:51
Consulte también stackoverflow.com/questions/22500/…
– Zan Lince
7 febrero 2012 a las 19:51
Busqué K&R y dice que si no hay una declaración previa de la función visible en el alcance, se supone que la primera instancia de uso de funciones es una declaración con tipo de retorno int y no se asume nada sobre los parámetros. Gracias por su entrada a todos.
– Bazuca
7 febrero 2012 a las 20:19
posible duplicado de ¿Se requieren prototipos para todas las funciones en C89, C90 o C99?
– Ciro Santilli Путлер Капут 六四事
13 de mayo de 2015 a las 7:26