0

I ran this program in GCC(gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)) on Linux. It successfully compiled using gcc myprog.c and run without any warnings or errors.

So, Why doesn't the compiler give any warnings or errors when only one argument is provided for main in C?

#include <stdio.h>

int main(int i)
{
    printf("%d\n", i);
}
msc
  • 33,420
  • 29
  • 119
  • 214

2 Answers2

5

With GCC 6 (on Linux/Debian/Sid/x86-64) my compiler does give some warning when compiling with gcc -Wall rsp.c -o rsp your rsp.c example.

rsp.c:3:5: warning: ‘main’ takes only zero or two arguments [-Wmain]
 int main(int i)
     ^~~~

But the C11 programming language (read n1570) does not specify when a compiler should warn. It mostly defines what are the correct possible programs and how should they behave. Read more about undefined behavior (I guess, but I am not sure, that you have one).

If you want to really understand what is actually happening in your case on your computer, study the source code of your compiler, the emitted assembler code (compile with gcc -S -fverbose-asm -O rsp.c then look into the generated rsp.s), the source code of your C standard library, of your crt0 runtime. Study also the ABI and the calling conventions relevant to your system.

I think you should be very scared of undefined behavior. Very bad things could happen.

As a practical advice when coding on Linux, always compile with -Wall and -g passed to gcc The -Wall option asks for nearly all warnings (and you could add -Wextra). The -g option asks for debug information. You'll then be able to use the gdb debugger to understand more what is happening at runtime.

Once you are confident in your code and have debugged it, consider compiling it with -O or -O2 to ask for optimization (in particular for benchmarking). (BTW, gcc can accept both -g and -O2). Read documentation on GCC command options.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
4

As per the C standard

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; or in some other implementation-defined manner.

If an implementation defines it to accept a single parameter, then it can.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • Historically, the definition `int main(int i)` should be OK. `i` will just be the number of program arguments and `argv[]` will be inaccessible. – Paul Ogilvie Feb 26 '17 at 15:26
  • @PaulOgilvie: I am not sure of that. I agree with you that *practically* it should often work. But I don't feel that is OK (it is UB). – Basile Starynkevitch Feb 26 '17 at 15:48
  • 2
    The definition of main in ISO 9899 only applies to hosted implementations. Freestanding implementations are free to define any startup function with any parameterization. There have probably been conforming hosted implementations which would fail at runtime with `int main(int i)`. It's possible ILE C for the AS/400 would have, for example. The real lesson here is "learn the language you're using". – Michael Wojcik Feb 26 '17 at 16:13
  • 1
    @MichaelWojcik A bit off-topic: I've read a little about the idiosyncrasies of the AS/400 and its ILE C. I can't think of what would cause `int main(int i)` to fail though, Care to elaborate? – a3f Feb 26 '17 at 17:41
  • 1
    @a3f I'm not sure it would - I only mentioned it because it's fairly strict, in part because of the capability architecture of the '400 (aka System i, etc). The ILE docs imply that the system is aware of omitted parameters, even for the PEP invocation of the main() UEP, and specify the allowed forms of main(); so it might detect this and raise a program check. Actually the older AS/400 C implementations, System/C and prior to that EPM C, might be more likely to object, but I don't remember how closely they conformed to the standard. – Michael Wojcik Feb 28 '17 at 16:11