5
votes

The standard says:

5.1.2.2.1 Program startup

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters: int main(void) { /* ... */ } or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared): int main(int argc, char argv[]) { / ... */ } or equivalent; 10) or in some other implementation-defined manner.

If I write this:

#include <stdio.h>

struct some_struct
{
    int i;
};

float main(struct some_struct s)
{
    printf("Why does this main get called?\n");
}

Actually, it gets called with any prototype, as I see, and there is no any runtime error.

Why isn't it forbidden? Are there no reasons for that? Also, how does it get called if the signature is wrong?

I've used gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

3
Compile with -Wall -Werroror -pedantic-errors and you'll see it is not allowed. - ouah
Basically, if main() isn't typed, it defaults to int, if it is typed and not to an int -- it is an error. - David C. Rankin
Understood about compile flags, but how does it get called then? It just looks up for the function with name "main" and ignores any arguments? - acrilige
The linker in C only looks at function names. Including the arguments in the linkage is a C++ feature, required to support function overloads. Well known as "name mangling". - Hans Passant
I've got it. Thanks. Might write an answer so that I could accept it - acrilige

3 Answers

3
votes

Starting with standard conformance:

1 In this International Standard, ‘‘shall’’ is to be interpreted as a requirement on an implementation or on a program; conversely, ‘‘shall not’’ is to be interpreted as a prohibition.

2 If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or run time constraint is violated, the behavior is undefined. [...]

Look at the emphasis on the paragraph you quoted:

[...]. It shall be defined with a return type of int and with [...]

In the case,

float main(struct some_struct s){...}  

"shall" requirement is outside of constraint because standard clearly states that main return type shall be int either with no parameters

int main(void) { /* ... */ }  

or with two parameters

 int main(int argc, char argv[]) { / ... */ }    

This means that behavior of your program is undefined.

2
votes

Your quote from the standard states that "some other implementation-defined manner". It appears that gcc is quite liberal in what it allows as signatures for main; it seems to ignore the parameter that you're passing. If you compile with gcc -Wall, you get warnings about main's prototype not being what it expects.

clang is less permissive about main's prototype. It will accept the return type of float with a warning, but will error out on the struct argument.

C looks up functions by name only, so the linker doesn't care about the unusual return type and parameters.

-1
votes

In C, if a function signature doesn’t specify any argument, it means that the function can be called with any number of parameters or without any parameters.

Hey checkout out this link - https://www.geeksforgeeks.org/difference-int-main-int-mainvoid/