This question already has answers here:
Alternative (K&R) C syntax for function declaration versus prototypes
(5 answers)
Closed 8 years ago.
I've seen a few function definitions like this recently while playing with GNU Bison:
static VALUE
ripper_pos(self)
VALUE self;
{
//code here
}
Why is the type of self outside of the parenthesis? Is this valid C?
Those are old K&R style function parameter declarations, declaring the types of the parameters separately:
int func(a, b, c)
int a;
int b;
int c;
{
return a + b + c;
}
This is the same as the more modern way to declare function parameters:
int func(int a, int b, int c)
{
return a + b + c;
}
The "new style" declarations are basically universally preferred.
This is the so-called "old" variant of declaring function arguments. In ye olden days, you couldn't just write argument types inside the parentheses, but you had to define it for each argument right after the closing parenthesis.
In other words, it is equivalent to ripper_pos( VALUE self )
Yes, it uses an older style of function definition in which the parameters, sans type, are listed in parentheses, followed by the declaration of those variables with their types before the opening brace of the function body. So self is of type VALUE.
This is old c. K&R C used this convention, before ANSI C enforced typed parameters.
static VALUE // A static function that returns 'VALUE' type.
ripper_pos(self) // Function 'ripper_pos' takes a parameter named 'self'.
VALUE self; // The 'self' parameter is of type 'VALUE'.
That's the old-style C function declaration syntax.
It is really old C code, where you first specify the argument names, and then their types. See for example here.
Related
This question already has answers here:
Alternative (K&R) C syntax for function declaration versus prototypes
(5 answers)
Closed 3 years ago.
I stumbled upon these lines when looking into putchar.c
I'm wondering about why the arguments ptr and c are declared outside the arguments body ?
Is this some kind of "good old way" or does it have some actual use ?
int
_putchar_r (ptr, c)
struct _reent *ptr;
int c;
{
return __sputc (c, _stdout_r (ptr));
}
Indeed it is the "olden" way of declaring a function's parameters.
I kind of like it, because it serves as a constant reminder that all a function's parameters are local variables that exist only in the scope of the function and that any argument passed into any function ALWAYS is a value copy.
Its a K&R C style introduced in classic C Programming Book
It is a function definition with an identifier list. Each identifier in the identifier list is declared before the compound statement of the function.
So a function can be defined either with a parameter type list or using the old style with an identifier list.
This question already has answers here:
Alternative (K&R) C syntax for function declaration versus prototypes
(5 answers)
Closed 6 years ago.
What are the differences between a K&R function declaration and an ANSI function declaration?
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;
}
I just want to add that in the traditional K & R style type modifiers for functions that return an int value aren't even necessary.
Consider the modern C11 notation of a simple HelloWorld program:
int main(int argc, char **argv) {
printf("hello world\n");
return 0;
}
This is equivalent to the K & R notation style:
main(argc, argv)
int argc;
char **argv;
{
printf("hello world\n");
return 0;
}
Note that the int before main() is ignored, but the code still compiles. That's a part of the K & R definition.
Quote Wikipedia:
In early versions of C, only functions that returned a non-int value needed to be declared if used before the function definition; a function used without any previous declaration was assumed to return type int, if its value was used.
--source: https://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C
This is arguably a legacy coding-style and should be avoided due to clarity issues, but quite often old algorithm textbooks favour this sort of K & R style.
This question already has answers here:
Alternative (K&R) C syntax for function declaration versus prototypes
(5 answers)
Closed 6 years ago.
What are the differences between a K&R function declaration and an ANSI function declaration?
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;
}
I just want to add that in the traditional K & R style type modifiers for functions that return an int value aren't even necessary.
Consider the modern C11 notation of a simple HelloWorld program:
int main(int argc, char **argv) {
printf("hello world\n");
return 0;
}
This is equivalent to the K & R notation style:
main(argc, argv)
int argc;
char **argv;
{
printf("hello world\n");
return 0;
}
Note that the int before main() is ignored, but the code still compiles. That's a part of the K & R definition.
Quote Wikipedia:
In early versions of C, only functions that returned a non-int value needed to be declared if used before the function definition; a function used without any previous declaration was assumed to return type int, if its value was used.
--source: https://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C
This is arguably a legacy coding-style and should be avoided due to clarity issues, but quite often old algorithm textbooks favour this sort of K & R style.
This question already has answers here:
What is this strange function definition syntax in C? [duplicate]
(6 answers)
Closed 8 years ago.
When reading some FreeBSD source code (See: radix.h lines 158-173), I found variable declarations that followed the "function heading" in the definition.
Is this valid in ISO C (C99)? when should this be done in production code instead of just declaring the variables within the "function heading?" Why is it being done here?
I refer to the function heading the string that looks like this: int someFunction(int i, int b) {
That looks like K&R (pre-ANSI) style. I don't think it's valid C99, but are they using C99? Joel
I think you are referring to the "old-fashioned" pre-ANSI way of declaring parameters in C. It looked something like this:
int foo(a, b)
int a,
int b
{
/* ... */
}
That may still be valid in C99, and will be accepted by compilers for backward-compatibility reasons, but it should be considered deprecated/archaic.
Er. Maybe I'm misunderstanding your question, but i and b in that snippet are parameters to the function. It's not some compact way of declaring variables within the function, like:
int someFunction() {
int i, b;
When you call someFunction, you pass it those arguments:
someFunction(1, 2); // `i` will be `1` and `b` `2` within `someFunction`
This question already has answers here:
Alternative (K&R) C syntax for function declaration versus prototypes
(5 answers)
Closed 8 years ago.
I've seen a few function definitions like this recently while playing with GNU Bison:
static VALUE
ripper_pos(self)
VALUE self;
{
//code here
}
Why is the type of self outside of the parenthesis? Is this valid C?
Those are old K&R style function parameter declarations, declaring the types of the parameters separately:
int func(a, b, c)
int a;
int b;
int c;
{
return a + b + c;
}
This is the same as the more modern way to declare function parameters:
int func(int a, int b, int c)
{
return a + b + c;
}
The "new style" declarations are basically universally preferred.
This is the so-called "old" variant of declaring function arguments. In ye olden days, you couldn't just write argument types inside the parentheses, but you had to define it for each argument right after the closing parenthesis.
In other words, it is equivalent to ripper_pos( VALUE self )
Yes, it uses an older style of function definition in which the parameters, sans type, are listed in parentheses, followed by the declaration of those variables with their types before the opening brace of the function body. So self is of type VALUE.
This is old c. K&R C used this convention, before ANSI C enforced typed parameters.
static VALUE // A static function that returns 'VALUE' type.
ripper_pos(self) // Function 'ripper_pos' takes a parameter named 'self'.
VALUE self; // The 'self' parameter is of type 'VALUE'.
That's the old-style C function declaration syntax.
It is really old C code, where you first specify the argument names, and then their types. See for example here.