C corner case and trap
I am surprised why this works?
short main [] ={};
This is the only content in the file. It compiles correctly on gcc. But when i run it prints segmentation fault. When i rename main, compiler gives errors. Can anyone ex开发者_运维知识库plain me what is going on here.
Apparently the linker doesn't know the type of global objects (like: variable or function), but only the address; so it links the program as if your variable was a function. Which crashes for obvious reasons.
Are you getting error like this?
Undefined symbols:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
This is not a compiler error, but a linker error.
In compilation, each source file is translated to an object file.
There is no check whether int main()
exists because the program may consist of multiple sources, and the main()
is only defined in one of these, or it doesn't even need to exist (e.g. in a dynamic library). Since the source
short main[] = {};
is considered a valid declaration (create a global short
array named main
and initialize to an empty array) by the compiler, it will not generate any errors.
The detection of whether int main()
exists is checked by the linker. The linker binds the compiled object files to a working executable. If the linker cannot find the symbol main
, it will complain like the one I described above. Unfortunately, the conventional C ABI does not differentiate between functions or or kinds of exported variables. So even if the main
is declared as an array, since the linker only knows "something called main
exists" and cannot check more, it will pass as well.
The result is that the program is generated without error although it is wrongly written.
When the program is run, the so-called main
does not hold executable code. Rather, it is just some data (likely zeroed). So the system may do anything unexpected (in your case, it is a SEGFAULT).
This can actually be caught when compiling with the -Wall
flag in gcc, which gives a warning:
<stdin>:1: warning: ‘main’ is usually a function
Try compiling with more options. :)
For example adding simple -Wall
gcc -Wall test.c -o t
test.c:1: warning: ‘main’ is usually a function
I have not read the relevant standard page, but apparently you just have to have main of some kind in order to compile, not necessarily a function...
精彩评论