9

For some odd reason I was copying an example in another language of which does not use types, and forgot to add one in to a function definition parameter, and it worked.

#include <stdio.h>

char toChar(n) {
  //sizeof n is 4 on my 32 bit system
  const char *alpha = "0123456789ABCDEF";
  return alpha[n];
}

int main() {
  putchar(toChar(15)); //i.e.
  return 0;
}

I am sure that main defaults to int by most compilers of some standard (but only return), is this also a behaviour true for other functions as well or is this implementation defined? It seems just out of the ordinary, my compiler is just a slightly outdated GCC port (MinGW).

Alexander
  • 1,053
  • 11
  • 16
  • Ah, my fun is over. When run under pedantic, `3: warning: type of "n" defaults to "int"` knew there was something helping me there. I apologize for the quick realization by myself. Maybe if somebody sheds some light if this is GCC-only. – Alexander May 04 '11 at 14:43
  • @Alexander: This is just K&R-style declaration, see http://stackoverflow.com/questions/1585390/c-function-syntax-parameter-types-declared-after-parameter-list – Erik May 04 '11 at 14:45
  • @Erik: You know, I thought the very same thing (declared first, typed after, type missing so defaults to int). I am glad I could make hands of this myself. – Alexander May 04 '11 at 14:46
  • In programming it is always good to switch the compiler into a mode for pedantic checks, turn all warnings on and handle warnings as errors. This might be harsh at first, but it helps to avoid a lot of trouble. – Rick-Rainer Ludwig May 04 '11 at 14:47
  • @Rick-Rainer, very true. I often use shorter hand comments (C++ style) and pedantic switch ruins that, although best of both worlds if I am writing unfamiliar code! – Alexander May 04 '11 at 14:50
  • You kids today. Never had to deal with default data types. Why back in the day we used to use FORTRAN implicit types and BASIC only gave us two characters for each variable name. You young folks today with your explicitly declared datatypes and long variable names, what is the world coming to? – David R Tribble May 04 '11 at 14:56
  • 1
    @Alexander: `-std=c99 -pedantic` will let you use C++-style comments. – Steve Jessop May 04 '11 at 15:30

3 Answers3

13

K&R-style function declaration:

void foo(n) 
    int n; 
{

}

If type isn't specified, it defaults to int. This is valid in C89, not C99

Erik
  • 88,732
  • 13
  • 198
  • 189
  • This is valid in C99. (In C89 you could also omit the `int n;` - in C99 that can no longer be omitted). – M.M Jul 22 '14 at 22:05
  • Just encountered this Q&A after succeeding compiling a C program in VS2015 without the `int n` declaration, so I believe that in can be omitted in C99 as well... – noamgot Dec 14 '17 at 12:28
5

@Erik's answer is correct, but (IMO) could be misunderstood rather easily.

What you have is a K&R style definition, that's entirely true. Since int is considered the default type, if you have something like: foo(n) { }, it means the return type and the type of n are both int by default.

C99 (mostly) removes the "default int" rule, but does not entirely remove K&R style definitions. That means the definition above is no longer allowed; to define foo with the same types as above, you could still use:

int foo(n)
int n;
{
}

I.e., the K&R style definition is still allowed, but you do have to specify the return type and the parameter type, even if the type is int.

This style of function definition is, however, obsolescent (per §6.11.7). It's really only still allowed for the sake of ancient (pre-standard) code. You don't want to write new code this way, even though it's technically still allowed. For new code, you clearly want to use a prototype-style definition:

int foo(int n) {}

For those who care about such things, the K&R style definition is still used in some new code though. Its terser style can be useful (using the term loosely) in code-golf.

As long as we're at it: @stijn's answer is sort of correct as well. In particular when a function is defined this way (I.e., K&R style), all arguments are subject to default promotions. That means if you pass an integer type smaller than int, it'll be promoted to int before being passed, and if you pass a float, it'll be promoted to double.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

afaik this is called argument promotion. i do not recall the exact rules, but it comes down to the compiler being allowed to use int for arguments when he (she?) doesn't know the function prototype yet.

stijn
  • 34,664
  • 13
  • 111
  • 163