A few questions about functions and arguments

Viewed 91

So I'm learning about functions in a book.

  1. It says we need to prototype or declare functions so the compiler can understand if they are correctly called or not.

But why does the main function works without a prototype?

  1. I used to write main functions in my learning process like this:

    int main(void)
    

    So it will not get any argument because of (void)

    I tried to run my program with argument for example > ./a.out 2

    int main(int y){ 
        printf("%s %d\n","y is",y); 
    } 
    

    When I run it normally y is 1, when run it with > ./a.out 1 y is 2, when there is more than one argument it increases by one. So it's not the right way but what causes this?

    Declaring y as char says nothing so my guess is it works like the return value of scanf(). It returns number of successful inputs.

2 Answers

A function must be either declared (i.e. a prototype) or defined before it is called. The main function is different from other functions in that it's called by the program startup code and not some other function.

There are however restrictions on what the signature of main can be. On a regular hosted implementation, the C standard says it can be either:

int main(void)

Or:

int main(int argc, char **argv)

The latter case is used to read command line arguments. argc contains the number of arguments passes, including the program name. argv contains the actual arguments as an array of char *.

Many systems also support:

int main(int argc, char **argv, char **envp)

Where envp contains the environment variables known to the program.

The prototype you're using: int main(int y) is not supported in any implementation I'm aware of, so attempting to use such a prototype for main invokes undefined behavior.

When I run it normally y is 1, when run it with > ./a.out 1 y is 2, when there is more than one argument it increases by one. So it's not the right way but what causes this?

The standard entry for program startup kind of answers both your questions:

N1570 § 5.1.2.2.1 Program startup

1 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[]) { /* ... */ }

[...]

As dbush already stated in the accepted answer these are the only two main implementations allowed by the standard.

The standard leaves the responsability of dealing with undefined constructs opened and imposes no requirements for what the behavior should be, a given implementation may deal with the situation in any way it considers appropriate, this is known as undefined behavior.

What seems to be happening is that your compiler is assuming that y is argc, which is allowed (as you can see in the second snippet of highlighted citation above), and argc stores the number of arguments in the command line, which is consistent with the results you're having, but again, this behavior may differ in different compilers, systems or even versions of the same compiler.

Related