change the entry point
C言語をはじめ習うときには、
#include <stdio.h> int main(void) { printf("Hello World\n"); return 0; }
なんて書かされますね。そして「どんなプログラムでもmain関数からはじまる」と教えられます。
でも、
#include <stdio.h> __attribute__((constructor)) void first() { printf("First\n"); } int main(void) { printf("Main\n"); return 0; }
と書いてコンパイルすると、
First Main
という出力結果になります。gcc依存のコードなのですが、__attribute__で宣言した関数(ここではfirst)はmain関数より前に呼ばれることになります。constructorではなくdestructorにすれば、main関数の後に呼ばれます。
で、もう一つ。こちらはエントリーポイントを変えてしまう方法。
/* entrypoint.c */ #include <stdio.h> #include <stdlib.h> int main(void) { printf("Main\n"); return 0; } int first() { printf("First\n"); main(); exit(0); }
と書いて、
gcc -e _first entrypoint.c
でコンパイルします。-e _firstはfirst関数をエントリーポイントに設定するということです。関数名の始めにアンダーバーを加えるのはmacの場合であって、linuxではアンダーバーは必要ないようです(未確認)。また、エントリーポイントを変えた場合はexit関数で終了させてやらなければいけないようです。これを忘れるとsegmentation faultとなります。
さてこれを実行すると、
First Main
となり、確かにfirst関数が先に呼ばれますね。もちろんmain関数消しても動きますよ。
さて、全く意味を感じないけども、いい勉強した気になれたので良しとします。