Sintaxis alternativa (K y R) C para la statement de funciones frente a prototipos

¿Qué es útil acerca de esta syntax de C – usando declaraciones de funciones de estilo ‘K & R’?

 int func (p, p2) void *p; int p2; { return 0; } 

Pude escribir esto en Visual Studios 2010beta

 //yes the params are flipped void f() { void *v=0; func(5,v); } 

No entiendo. ¿Cuál es el punto de esta syntax? Puedo escribir:

 int func (p, p2) int p2; { return 0; } //and write int func (p, p2) { return 0; } 

Lo único que parece especificar es cuántos parámetros usa y el tipo de devolución. Supongo que los parámetros sin tipos son geniales, pero ¿por qué permitirlo y el int paranName después del declarador de funciones? Es raro.

También es esto todavía estándar C?

La pregunta que hace es realmente dos preguntas, no una. La mayoría de las respuestas intentaron cubrir todo el asunto con una respuesta genérica de “esto es estilo K & R”, mientras que de hecho, solo una pequeña parte tiene algo que ver con lo que se conoce como estilo K & R (a menos que vea todo el lenguaje C como “K & R-style” de una forma u otra 🙂

La primera parte es la extraña syntax utilizada en la definición de la función

 int func(p, p2) void *p; int p2; /* < - optional in C89/90, but not in C99 */ { return 0; } 

Esta es en realidad una definición de función estilo K & R. Otra respuesta ha cubierto esto bastante bien. Y no hay mucho para eso, en realidad. La syntax está en desuso, pero todavía totalmente compatible incluso en C99 (excepto para la regla "no implicit imp" en C99, lo que significa que en C99 no puede omitir la statement de p2 ).

La segunda parte tiene poco que ver con el estilo K & R. Me refiero al hecho de que la función se puede llamar con argumentos "intercambiados", es decir, no se realiza ninguna comprobación de tipo de parámetro en dicha llamada. Esto tiene muy poco que ver con la definición del estilo de K & R per se, pero tiene todo que ver con que su función no tenga prototipo. Ya ves, en C cuando declaras una función como esta

 int foo(); 

en realidad declara una función foo que toma un número no especificado de parámetros de tipo desconocido . Puedes llamarlo como

 foo(2, 3); 

y como

 j = foo(p, -3, "hello world"); 

y así sucesivamente (entiendes la idea);

Solo la llamada con los argumentos adecuados "funcionará" (lo que significa que los demás producen un comportamiento indefinido), pero depende completamente de usted asegurar su corrección. El comstackdor no está obligado a diagnosticar los incorrectos, incluso si de alguna manera sabe mágicamente los tipos de parámetros correctos y su número total.

En realidad, este comportamiento es una característica del lenguaje C. Una peligrosa, pero una característica sin embargo. Te permite hacer algo como esto

 void foo(int i); void bar(char *a, double b); void baz(void); int main() { void (*fn[])() = { foo, bar, baz }; fn[0](5); fn[1]("abc", 1.0); fn[2](); } 

es decir, mezclar diferentes tipos de funciones en una matriz "polimórfica" sin ningún tipo de difusión (sin embargo, no se pueden usar tipos de funciones variadas). Nuevamente, los peligros inherentes de esta técnica son bastante obvios (no recuerdo haberlo usado nunca, pero puedo imaginar dónde puede ser útil), pero eso es C después de todo.

Finalmente, el bit que vincula la segunda parte de la respuesta con la primera. Cuando realiza una definición de función de estilo K & R, no presenta un prototipo para la función. En lo que respecta al tipo de función, su definición de func declara func como

 int func(); 

es decir, no se declaran ni los tipos ni la cantidad total de parámetros. En tu publicación original dices "... parece especificar cuántos params usa ...". Formalmente hablando, ¡no es así! Después de su definición de func estilo K & R de dos parámetros, puede llamar a func como

 func(1, 2, 3, 4, "Hi!"); 

y no habrá ninguna violación de restricción en él. (Normalmente, un comstackdor de calidad le dará una advertencia).

Además, un hecho que a veces se pasa por alto es que

 int f() { return 0; } 

también es una definición de función estilo K & R que no introduce un prototipo. Para que sea "moderno" tendrías que poner un void explícito en la lista de parámetros

 int f(void) { return 0; } 

Finalmente, contrariamente a una creencia popular, tanto las definiciones de funciones estilo K y R como las declaraciones de funciones no prototipadas son totalmente compatibles con C99. El primero ha quedado obsoleto desde C89 / 90, si no recuerdo mal. C99 requiere que la función se declare antes del primer uso, pero no se requiere que la statement sea un prototipo. La confusión aparentemente surge de la popular confusión terminológica: mucha gente llama a cualquier statement de función "un prototipo", mientras que de hecho "statement de función" no es lo mismo que "prototipo".

Esta es la syntax de K & R C bastante antigua (anteriores a ANSI / ISO C). Hoy en día, ya no deberías usarlo (ya que ya has notado su gran desventaja: el comstackdor no verificará los tipos de argumentos por ti). El tipo de argumento realmente se predetermina a int en su ejemplo.

En el momento, se utilizó esta syntax, uno a veces encontraría funciones como

 foo(p, q) { return q + p; } 

que en realidad era una definición válida, ya que los tipos para foo , p y q defecto en int .

Esto es simplemente una syntax antigua, que es anterior a la syntax “ANSI C” con la que quizás esté más familiarizado. Se llama ” K & R C “, por lo general.

Los comstackdores lo admiten completo, y para poder manejar bases de código antiguas, por supuesto.

Esta es la syntax original de K & R antes de que C se estandarizara en 1989. C89 introdujo prototipos de funciones, tomados de C ++, y desaprobó la syntax de K & R. No hay ninguna razón para usarlo (y muchas razones para no hacerlo) en un código nuevo.

Esa es una reliquia de cuando C no tenía prototipos para funciones. En aquel entonces, (creo) se suponía que las funciones devolvían int y se suponía que todos sus argumentos eran int . No se realizó ninguna comprobación en los parámetros de la función.

Es mucho mejor utilizar prototipos de función en el lenguaje C actual.
Y debe usarlos en C99 (C89 todavía acepta la syntax anterior).

Y C99 requiere que se declaren las funciones (posiblemente sin un prototipo). Si está escribiendo una nueva función desde cero, debe proporcionar una statement … también conviértalo en un prototipo: no pierde nada y obtiene una verificación adicional del comstackdor.

Es un estilo más antiguo de declaraciones de funciones. Por favor mira este enlace.

https://stackoverflow.com/questions/22500/what-are-the-major-differences-between-ansi-c-and-kr-c texto de enlace