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

Time:10-02

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?

Note: I've kept the mistake in the question so that answers and comments wouldn't need to be changed.

Another note: As pointed out by @Steve Summit and @nick, Objective-C is a strict superset of C, which means that all C code is also valid Objective-C code and thus has to show this behavior regarding functions.

CodePudding user response:

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 function's call(s) matched its definition 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.


Two additional notes: You asked about Objective C, but I don't know anything about that language, so I can't address that point. And you said that for a function without a prototype, "trying to input an argument to it (as the first and the only argument) doesn't cause a compilation error", but in fact, you can pass any number or arguments to such a function, without error.

CodePudding user response:

Because function prototypes were not a part of pre-standard C, functions could be declared only with empty parentheses:

extern double sin();

All existing code used that sort of notation. The standard would have failed had such code been made invalid, or made to mean “zero arguments”.

So, in standard C, a function declaration like that means “takes an undefined list of zero or more arguments”. The standard does specify that all functions with a variable argument list must have a prototype in scope, and the prototype will end with , ...). So, a function declared with an empty argument list is not a variadic function (whereas printf() is variadic).

Because the compiler is not told about the number and types of the arguments, it cannot complain when the function is called, regardless of the arguments in the call.

  • Related