views:

119

answers:

3

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 explain me what is going on here.

+4  A: 

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.

ammoQ
+1  A: 

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

Sint
`gcc -ansi -pedantic -W -Wall`
Philip Potter
+3  A: 

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
KennyTM
Ok, i got it, but one more question crops up in my mind, can we write something in this array that will do something useful like printing hello. There is a gcc option fwritablestrings, what it will do?
evil.coder
short main[] = {};I don't think it's valid declaration. zero initializer? maybe valid C99?
Nyan
@Nyan: Maybe GCC extension. Anyway, that's not the main point.
KennyTM