P0W P0W - 1 month ago 17
C Question

C functions declaration in K&R

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.

Answer

"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!

Comments