programa lenguaje general estructura descargar c c99 c89

lenguaje - ¿Se requieren prototipos para todas las funciones en C89, C90 o C99?



ansi c++ (6)

Para ser realmente compatible con los estándares, ¿todas las funciones en C (a excepción de las principales) tienen un prototipo, incluso si solo se usan después de su definición en la misma unidad de traducción?


A lo mejor de mi conocimiento (en ANSI C89 / ISO C90), no. No estoy seguro acerca de C99; sin embargo, yo esperaría lo mismo.

Nota personal: solo escribo prototipos de funciones cuando ...

  1. Necesito (cuando A () llama a B () y B () llama A ()), o
  2. Estoy exportando la función; de lo contrario, se siente superfluo.

Depende de lo que quiere decir con ''verdaderamente compatible con los estándares''. Sin embargo, la respuesta breve es "es una buena idea asegurarse de que todas las funciones tengan un prototipo en el alcance antes de ser utilizadas".

Una respuesta más calificada observa que si la función acepta argumentos variables (especialmente la familia de funciones printf() ), entonces un prototipo debe estar dentro del alcance para cumplir estrictamente con los estándares. Esto es cierto para C89 (de ANSI) y C90 (de ISO; lo mismo que C89, excepto para la numeración de secciones). Sin embargo, aparte de las funciones ''varargs'', las funciones que devuelven un int no tienen que ser declaradas, y las funciones que devuelven algo que no sea int necesitan una declaración que muestre el tipo de retorno pero no necesitan el prototipo para la lista de argumentos.

Sin embargo, tenga en cuenta que si la función toma argumentos que están sujetos a ''promociones normales'' en ausencia de prototipos (por ejemplo, una función que toma una char o un short , ambos convertidos a int ; más en serio, tal vez, un función que toma un float lugar de un double ), entonces se necesita un prototipo. El estándar era poco estricto en cuanto a esto para permitir que el viejo código C compilara bajo compiladores conformes estándar; el código anterior no se escribió para preocuparse de garantizar que las funciones se declararan antes del uso, y por definición, el código anterior no usaba prototipos, ya que no estaban disponibles en C hasta que hubo un estándar.

C99 no permite ''int'' implícito ''... eso significa que ambos casos de oddball como'' static a; ''(un int por defecto) y también declaraciones de funciones implícitas. Estos se mencionan (junto con otros 50 cambios importantes) en el prólogo de ISO / IEC 9899: 1999, que compara ese estándar con las versiones anteriores:

  • eliminar implicit int
    ...
  • eliminar declaración de función implícita

En ISO / CEI 9899: 1990, §6.3.2.2 Llamadas de función declaradas:

Si la expresión que precede a la lista de argumentos entre paréntesis en una llamada a función consiste únicamente en un identificador, y si no hay ninguna declaración visible para este identificador, el identificador se declara implícitamente exactamente como si, en el bloque más interno que contiene la llamada a la función, la declaración:

extern int identifier();

apareció. 38

38 Es decir, un identificador con alcance de bloque declarado para tener un enlace externo con la función de tipo sin información de parámetro y devolver un int . Si de hecho no se define como tener el tipo "función que devuelve int ", el comportamiento no está definido.

Este párrafo falta en el estándar de 1999. Todavía no he rastreado el cambio en la verbosidad que permite la static a; en C90 y no lo permite (requiere static int a; ) en C99.

Tenga en cuenta que si una función es estática, puede definirse antes de ser utilizada y no debe estar precedida por una declaración. Se puede persuadir a GCC para que intente si una función no estática se define sin una declaración que la preceda ( -Wmissing-prototypes ).


No, las funciones no siempre necesitan un prototipo. El único requisito es que una función sea "declarada" antes de usarla. Hay dos formas de declarar una función: escribir un prototipo, o escribir la función en sí (llamada "definición"). Una definición es siempre una declaración, pero no todas las declaraciones son definiciones.


Sí, cada función debe tener un prototipo, pero ese prototipo puede aparecer en una declaración separada o como parte de la definición de la función. Las definiciones de funciones escritas en C89 y arriba tienen prototipos, pero si escribes cosas en el estilo clásico de K & R, entonces:

main (argc, argv) int argc; char **argv; { ... }

entonces la definición de función no tiene prototipo. Si escribe el estilo ANSI C (C89), entonces:

main (int argc, char **argv) { ... }

entonces la definición de la función tiene un prototipo.


Un prototipo es una declaración de función que especifica los tipos de los parámetros de la función.

Pre-ANSI C (el lenguaje descrito por la primera edición de 1978 de Kernighan & Ritchie "The C Programming Language") no tenía prototipos; no fue posible para una declaración de función describir el número o tipos de los parámetros. Depende de la persona que llama para pasar el número correcto y el tipo de argumentos.

ANSI C introdujo "prototipos", declaraciones que especifican los tipos de los parámetros (una característica tomada de principios de C ++).

A partir de C89 / C90 (las normas ANSI e ISO describen el mismo idioma), es legal llamar a una función sin declaración visible; se proporciona una declaración implícita. Si la declaración implícita es incompatible con la definición real (por ejemplo, llamar a sqrt("foo") , entonces el comportamiento no está definido. Ni esta declaración implícita ni una declaración no prototipo pueden ser compatibles con una función variadica, por lo que cualquier llamada a un La función variadica (como printf o scanf ) debe tener un prototipo visible.

C99 dejó caer declaraciones implícitas. Cualquier llamada a una función sin una declaración visible es una violación de restricción, que requiere un diagnóstico de compilador. Pero esa declaración todavía no se requiere para ser un prototipo; puede ser una declaración antigua que no especifica tipos de parámetros.

C11 no realizó cambios significativos en esta área.

Incluso a partir del estándar ISO C 2011, las declaraciones y definiciones de funciones antiguas (que han sido "obsoletas" desde 1989) todavía se permiten en el código conforme.

Para todas las versiones de C que datan de 1989, como una cuestión de estilo, hay muy pocas razones para no usar prototipos para todas las funciones. Las declaraciones y definiciones de estilo antiguo se conservan solo para evitar descifrar el código anterior.


Un buen consejo al escribir nuevas funciones es escribirlas al revés con la tecla en la parte inferior para que cuando cambies de opinión sobre los argumentos de la función o el tipo de devolución no tengas que arreglar el prototipo también. Constantemente arreglar prototipos y lidiar con todas las advertencias del compilador cuando están desactualizados se vuelve realmente tedioso.

Una vez que tenga sus funciones funcionando sin problemas, mueva el código a un módulo bien nombrado y coloque los prototipos en un archivo .h del mismo nombre. Ahorra tiempo serio. La mayor ayuda de productividad que he encontrado en 5 años.