I want to compile this code:

void function () { puts("Hello world"); } main = function; 

In some places, it compiles , but when executed it falls with an error, in places it does not compile :

 prog.c:5:1: error: initializer element is not computable at load time main = function; ^ 

How to make it compile, run and not fall at least somewhere?


http://ideone.com/BZMp2V - changing void to int and adding return 0 does not help:

 int function () { puts("Hello world"); return 0; } main = function; 

On ideone, programs are 32-bit , so the pointer to the implicit int is also not associated with a custom pointer.

  • It remains to try to assign for = while; ... :) By the way, you can compile if you declare main as a function pointer. VC does not even swear at the absence of an entry point. But it falls ... - Harry
  • @Harry, I definitely saw a workable code somewhere with main= . - Qwertiy
  • Just to put a minus. Is it really not interesting? (( - Qwertiy
  • gcc compiles. with warnings, but burst :) - PinkTux
  • @Harry, by the way, by the second link warning: prog.c:5:1: warning: 'main' is usually a function [-Wmain] - I draw attention to the word usually - that is, usually, but not always. - Qwertiy

3 answers 3

Quest completed, sir!

 #include <stdio.h> #include <stdlib.h> void func () { puts("xa-xa-xa"); exit(0); } void *main = func; avp@wubu:hashcode$ gcc tc --entry=func && ./a.out xa-xa-xa avp@wubu:hashcode$ 

True, I had to add exit() .

Without exit falls. If you look in gdb,

 (gdb) layout asm 

then func() ends like this

 0x400535 <func+15> pop %rbp │ 0x400536 <func+16> retq │ 

Look at the stack

 (gdb) si (gdb) p $sp $3 = (void *) 0x7fffffffde70 (gdb) p *(0x7fffffffde70) $5 = 1 (gdb) 

and see here lies 1, not a normal return address

  • --entry=func - isn’t this a random entry point? - Qwertiy
  • Why exit? Doesn't the execution stop itself? :-) - Grundy Nov.
  • @Grundy, but with trash code in eax . And exit makes a beautiful zero. UPDATE: Hmm .. eax or ax ? - Qwertiy
  • @Qwertiy, does not some return do the same? And why with main it is not necessary to add exit? - Grundy Nov.
  • @Grundy, at the end of main, return 0; . More precisely, the pluses are not necessary - there the compiler will add it himself. But in si, no pluses needed. And here si. int func() { ... return 0; } int func() { ... return 0; } most likely will work. - Qwertiy

For each problem there is a #define :

 void function () { puts("Hello world"); } #define main static main #define function 0 main = function; 

 int main() { function(); } 

Performance check

  • 3
    well not :-) this is not sporty :) - Grundy
  • @Grundy do not see tags without-define :) - αλεχολυτ

Alternatively, use nested functions ( gcc extension ):

 void f() { void (*main)(); void function () { puts("Hello world"); } main = function; main(); } int main() { f(); }