Rhythm & Biology

Engineering, Science, et al.

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関数消しても動きますよ。


さて、全く意味を感じないけども、いい勉強した気になれたので良しとします。