14

Case 1:

void hello(void) { //something } int main() { hello(1); //error return 0; } 

Case 2:

int main(void) { //something return 0; } 

Execution:

./a.out something something //No error, Why? 

Why there is no error? main will not be able to take any arguments. So why it is possible to provide arguments from the command line?

5
  • Why would you expect an error? Commented Oct 24, 2015 at 10:40
  • @OliverCharlesworth Because we are passing argument to main? compiler doesn't come into picture but at runtime/loadtime why there is no error? Commented Oct 24, 2015 at 10:43
  • 2
    The shell always sends its arguments to the program - even if you provide none (usually it sends argv[0]). main is not the same kind of function as hello. Commented Oct 24, 2015 at 10:54
  • I'm interested in hearing the answer too. There must be something inside the runtime that calls main with those arguments. So why is there no linker error when you define a main that deviates from the standard? (Even main(float) generates only a warning, no error. And only with -Wall even.) Commented Oct 24, 2015 at 11:00
  • 1
    Out of curiosity, I performed a little experiment. I compiled the same program twice, once with each different signature. (VS2013 if you're interested, because it's what I had on hand.) Ignoring debugging information and timestamps, the two resulting files were exactly the same, down to the byte. This indicates to me that the compiler either replaces the void signature with the standard one (that wouldn't change your program at all), or is smart enough to know that it doesn't matter if you aren't using the args anyway. (Of course, we'd expect the compiler to know that. :) ) Commented Oct 24, 2015 at 20:37

5 Answers 5

14

Because the C compiler and the command line interpreter (or whatever is used to invoke your program) are different things.

The C language allows various ways how main () could be declared.

The command line interpreter will make any arguments available to the program. If the program ignores them, that's none of its business.

The command line interpreter doesn't even know that you used C to compile your program. On my computer, the program could be written in C, C++, Objective-C, Objective-C++, Swift, Fortran, Ada, and so on. Each of these compilers may or may not do things to accept commands from the command line.

Sign up to request clarification or add additional context in comments.

Comments

9

Not checking the specification nor compiled result, it will cause no error because the C runtime will get the arguments and pass them to main(), but this type of main() will ignore the passed arguments, and if it is caller's duty to clean up the memory (stack) used as the arguments, it will cause no problems just as getting some arguments and not using them in the code.

This code won't emit errors in C:

void hello(); // in C, the compiler won't check arguments int main() { hello(1); //no error return 0; } void hello(void) { //something } 

9 Comments

@Jongware The arguments passed to main are cleaned off the stack by the function that calls main, which is a shim provided by the C library, and that function doesn't know or care how main was declared. This isn't special to main; this is the normal C calling convention for all functions. (Compiler extensions like __stdcall can change the convention. Bad Things will happen if you apply them to main--or to any other function called by the C library.)
@Jongware Ah, the other thing you might've been trying to ask. Where does argv come from in the first place? The kernel loads it into memory along with the program, as part of the execve operation, and constructs an initial call frame that tells the C library's startup code where to find it. It's usually at the very top of the stack, but it doesn't have to be, and it's never deallocated.
@Jongware If the C library's startup code were to return from that initial stack frame, the program would crash. It is required to call exit instead. See for instance the very end of sourceware.org/git/?p=glibc.git;a=blob;f=csu/libc-start.c .
@zwol: that must be the answer the OP is looking for. The runtime startup always tells the C code where to find the arguments - whether there is one or not. And it does not care if the C code actually bothers to check.
You can't rely on this kind of code compiling and running without errors. C11 standard, 6.5.2.2.6: "If the number of arguments does not equal the number of parameters, the behavior is undefined." You're relying on implementation quirks, and a different implementation or any sort of optimization might break this code.
|
5

Because ./a.out something something is not directly calling your main function. THe main function is being called by the c runtime library. The command line arguments are placed in a region somewhere on the stack (very beginning) by the loader/c runtime. It is upto you if you want to access these arguments or not.

Plus as pointed out in one of the comments as well at least one command line argument is always passed anyways (the name of the program ./a.out to be precise) - so you must have wondered about an error in that case as well.

Comments

3

Recall that ISO C specifies the two possible signatures of main: int main(void) and int main(int, char *[]) and the equivalent versions thereof, like int main(int, char **) because of array-to-pointer decay. This is covered more in detail here.

This question can be answered by considering the opposite question: how does the C runtime know what main to call? C doesn't have overload resolution! This is explained here. Briefly, the others are pushed but not accessed because there's no indication from C to do that.

Comments

2

When you compile your program using gcc program_name.c, compiler will report any possible compile time warning or error. Since the command line arguments are not passed at the compile time, compiler is unaware of it and program just ignore that arguments.

In case of hello, compiler knows the prototype of this function and expects no argument to be passed in its call and hence reports error in case of any argument passed to it.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.