What are the differences between a K&R function declaration and an ANSI function declaration?
A function declaration introduces an identifier that designates a function and, optionally, specifies the types of the function parameters (the prototype). Function declarations (unlike definitions) may appear at block scope as well as file scope.
A function consist of two parts: Declaration: the function's name, return type, and parameters (if any) Definition: the body of the function (code to be executed)
An implicitly declared function is one that has neither a prototype nor a definition, but is called somewhere in the code. Because of that, the compiler cannot verify that this is the intended usage of the function (whether the count and the type of the arguments match).
K&R syntax is obsolete, you can skip it unless you have to maintain very old code.
// K&R syntax int foo(a, p) int a; char *p; { return 0; } // ANSI syntax int foo(int a, char *p) { return 0; }
Legacy K&R-Style Declarations/Definitions
When Kernighan and Ritchie first published "The C Programming Language", C didn't yet offer full function prototypes. Forward declarations of functions existed, but with the sole purpose of indicating a return type. For functions that returned int
, they weren't required until C99.
By C89, the notion of a function prototype, which also specifies the types of the parameters (and, implicitly, their number) had been added. Since a prototype is also a type of function declaration, the unofficial term "K&R function declaration" is sometimes used for a function declaration that is not also a prototype.
// K&R declarations, we don't know whether these functions have parameters. int foo(); // this declaration not strictly necessary until C99, because it returns int float bar(); // Full prototypes, specifying the number and types of parameters int foo(int); float bar(int, float); // K&R definition of a function int foo(a) int a; // parameter types were declared separately { // ... return 0; } // Modern definition of a function float bar(int a, float b) { // ... return 0.0; }
The Accidental K&R Declaration
It's worth noting that newcomers to C may accidentally use K&R declarations when they intend to use a full prototype, because they may not realize that an empty parameter list must be specified as void
.
If you declare and define a function as
// Accidental K&R declaration int baz(); // May be called with any possible set of parameters // Definition int baz() // No actual parameters means undefined behavior if called with parameters. // Missing "void" in the parameter list of a definition is undesirable but not // strictly an error, no parameters in a definition does mean no parameters; // still, it's better to be in the habit of consistently using "void" for empty // parameter lists in C, so we don't forget when writing prototypes. { // ... return 0; }
...then you have not actually given a prototype for a function that takes no parameters, but a declaration in K&R-style for a function that accepts an unknown number of parameters of unknown type.
AnT notes in this answer to a similar question that this syntax is deprecated but still legal as of C99 (and that function pointers to functions with unknown number and type of parameters still have potential applications, though at high risk of undefined behavior); as such, compliant compilers will, at best, produce a warning if a function is declared or called without a proper prototype.
Calling functions without prototypes is less safe, because the compiler cannot verify that you have passed the correct number and types of parameters in the correct order; undefined behavior results if the call is not actually correct.
The correct way to declare and define a parameterless function is, of course:
// Modern declaration of a parameterless function. int qux(void); // "void" as a parameter type means there are no parameters. // Without using "void", this would be a K&R declaration. // Modern definition of a parameterless function int qux(void) { // ... return 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With