Why does a function in C(or Objective C) with no listed arguments allow inputting one argument?

In C when a function is declared like void main(); trying to input an argument to it(as the first and the only argument) doesn’t cause a compilation error and in order to prevent it, function can be declared like void main(void);. By the way, I think this also applies to Objective C and not to C++. With Objective C I am referring to the functions outside classes. Why is this? Thanks for reaching out. I imagine it’s something like that in Fortran variables whose names start with i, j, k, l, m or n are implicitly of integer type(unless you add an implicit none).

Edit: Does Objective C allow this because of greater compatibility with C, or is it a reason similar to the reason for C having this for having this?

>Solution :

In early (pre-ANSI) C, a correct match of function arguments between a function’s definition and its calls was not checked by the compiler.

I believe this was done for two reasons:

  1. It made the compiler considerably simpler
  2. C was always designed for separate compilation, and checking consistency across translation units (that is, across multiple source files) is a much harder problem.

So, in those early days, making sure that a functions call matched its arguments was the responsibility of the programmer, or of a separate program, lint.

The lax checking of function arguments also made varargs functions like printf possible.

At any rate, in the original C, when you wrote

extern int f();

, you were not saying "f is a function accepting no arguments and returning int". You were simply saying "f is a function returning int". You weren’t saying anything about the arguments.

Basically, early C’s type system didn’t even have a way of recording the parameters expected by a function. And that was especially true when separate compilation came into play, because the linker resolved external symbols based pretty much on their names only.

C++ changed this, of course, by introducing function prototypes. In C++, when you say extern int f();, you are declaring a function that explicitly takes 0 arguments. (Also a scheme of "name mangling" was devised, which among other things let the linker do some consistency checking at link time.)

Now, this was all somewhat of a deficiency in old C, and the biggest change that ANSI C introduced was to adopt C++’s function prototype notation into C. It was slightly different, though: to maintain compatibility, in C saying extern int f(); had to be interpreted as meaning "function returning int and taking unspecified arguments". If you wanted to explicitly say that a function took no arguments, you had to (and still have to) say extern int f(void);.

There was also a new ... notation to explicitly mark a function as taking variable arguments, like printf, and the process of getting rid of "implicit int" in declarations was begun.

All in all it was a significant improvement, although there are still a few holes. In particular, there’s still some responsibility placed on the programmer, namely to ensure that accurate function prototypes are always in scope, so that the compiler can check them. See also this question.

Leave a Reply