13

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.

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
P0W
  • 46,614
  • 9
  • 72
  • 119

4 Answers4

22

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

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
8

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • +1 Thanks for last clarification. Could you please give an example where `int` is not assumed by default ? – P0W Aug 25 '13 at 04:56
  • @P0W: I'm not sure what you mean exactly. What I'm saying in my answer is that in the above example `b` is NOT assumed to be `int` just because its type is missing from function parameter list. In order to determine the type of `b`, instead of jumping to immediate conclusions the compiler will continue to look further. It will discover the `char b` declaration and realize that `b` is supposed to be a `char`. – AnT stands with Russia Aug 25 '13 at 17:33
4

In C89, the default variable type is int: it is defined as implicit int. This rule has been revoked in C99.

In your example, it is compiled as:

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

foo(int a,int b){a=2; b='z';}
aymericbeaumet
  • 6,853
  • 2
  • 37
  • 50
  • 3
    Well, almost. Actually, it's compiled as `main(a,b,c,d) int a,b,c,d;`. The difference is subtle, but with the K&R syntax, you can do dumb things like calling any of these functions with any number and type of parameters without warnings (see, for example, http://stackoverflow.com/q/18202232/1204143) – nneonneo Aug 24 '13 at 18:35
  • Any justification for this `foo(a,b,c){printf("%s-%s-%s", a,b,c); } main(a,b,c,d){foo("this", "shouldn't", "work");}` It simply works. – P0W Aug 24 '13 at 18:41
  • @P0W Your code snippet segfaults when I tried to compile and run it. Did it work for you? – aymericbeaumet Aug 24 '13 at 18:44
  • @abeaumet Looks like its UB, with `-Wall` it throws warning – P0W Aug 24 '13 at 18:48
  • @P0W On some systems int and pointers have the same memory size. So it may work in some specific cases. Of course, it generates warnings. Try to add `-Wextra`. – aymericbeaumet Aug 24 '13 at 18:52
  • @P0W Increase level of strictness and you will get warning for `printf` which says `warning: format argument is not a pointer (arg 2)`. – Dayal rai Aug 24 '13 at 18:55
4

The default parameter is of int type in C and about K & R syntax please have a look here and here.

Community
  • 1
  • 1
Dayal rai
  • 6,548
  • 22
  • 29