Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C functions declaration in K&R

Tags:

c

I'm not familiar with K&R style function declaration.

Following compiles, with warning (just related to return value of main that too with -Wall) but what are the data types of variables used ?

main(a, b, c, d){
    printf("%d", d);
}

foo(a, b){
     a = 2; 
     b = 'z';
}

If this is a asked before please provide the link in comment section. I couldn't find something similar.

Edit

I just came across an obfuscated C code, which uses these.
But I can assure you, I won't be using such syntax in C programming.

like image 474
P0W Avatar asked Aug 24 '13 18:08

P0W


People also ask

What is C function declaration?

Declaration: the function's name, return type, and parameters (if any) Definition: the body of the function (code to be executed)

Does C require function declaration?

Actually, it is not required that a function be declared before use in C. If it encounters an attempt to call a function, the compiler will assume a variable argument list and that the function returns int.

What is function declaration of function?

The function declaration (function statement) defines a function with the specified parameters. You can also define functions using the Function constructor and a function expression.


2 Answers

"K&R C" refers to the language defined by the 1978 first edition of Kernighan & Ritchie's book "The C Programming Language".

In K&R (i.e., pre-ANSI) C, entities could commonly be declared without an explicit type, and would default to type int. This goes back to C's ancestor languages, B and BCPL.

main(a,b,c,d){
    printf("%d", d);
}

That's nearly equivalent to:

int main(int a, int b, int c, int d) {
    printf("%d", d);
}

The old syntax remained legal but obsolescent in ANSI C (1989) and ISO C (1990), but the 1999 ISO C standard dropped the "implicit int" rule (while keeping the old-style declaration and definition syntax).

Note that I said it's nearly equivalent. It's essentially the same when viewed as a definition, but as a declaration it doesn't provide parameter type information. With the old-style definition, a call with the wrong number or types of arguments needn't be diagnosed; it's just undefined behavior. With a visible prototype, mismatched arguments trigger a compile-time diagnostic -- and, when possible, arguments are implicitly converted to the parameter type.

And since this is a definition of main, there's another problem. The standard only specifies two forms for main (one with no arguments and one with two arguments, argc and argv). An implementation may support other forms, but one with four int arguments isn't likely to be one of them. The program's behavior is therefore undefined. In practice, it's likely that d will have some garbage value on the initial call. (And yes, a recursive call to main is permitted in C, but hardly ever a good idea.)

foo(a,b){
    a = 2;
    b = 'z';
}

This is nearly equivalent to:

int foo(int a, int b) {
    a = 2;
    b = 'z';
}

(And note that 'z' is of type int, not of type char.)

And again, the old form doesn't give you parameter type checking, so a call like:

foo("wrong type and number of arguments", 1.5, &foo);

needn't be diagnosed.

The bottom line: It's good to know how K&R-style function declarations and definitions work. There's still old code that uses them, and they're still legal (but obsolescent) even in C2011 (though without the "implicit int" rule). But there is very nearly no good reason to write code that uses them (unless you're stuck using a very old compiler, but that's rare and becoming rarer.)

But I can assure you, I won't be using such syntax in C programming.

Excellent!

like image 61
Keith Thompson Avatar answered Oct 09 '22 17:10

Keith Thompson


In K&R style function definition the type of the parameter is specified by a dedicated set of declarations that is placed between the function "signature" itself and the actual function body. For example, this function definition

void foo(a, b, c)
double a;
char b;
{
  ...
}

uses parameters of type double, char and int. This is actually where and how the "implicit int" rule comes into play: since parameter c was not mentioned by the above declaration list, it is assumed to have type int.

Note the important detail, which I believe is not made clear enough by other answers: parameter c has type int not because the type is missing in function parameter list, but rather because it is not mentioned in the sequence of declarators that follows the function "signature" (before the function body). In K&R-style declarations types are always missing from function parameter list (that's the defining feature of K&R declaration), yet it does not immediately mean that all parameters are assumed to have type int.

P.S. Note that C99 still supports K&R style declarations, but since C99 outlawed the "implicit int" rule, it requires you to mention all function parameters in that declaration list after the function "signature". The above example will not compile in C99 for that reason. int c has to be added to the declaration list.

like image 37
AnT Avatar answered Oct 09 '22 15:10

AnT