开发者

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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜