てきとうなメモ

本の感想とか技術メモとか

GCCの#pragma

昔のGCCは#pragmaを見つけるとrogue,hack,ハノイの塔(emacs上で)を実行していたらしい。#pragmaは標準ではなく処理系依存だから何をしても良いだろうということみたい。

というのが「エキスパートCプログラミング」に書かれてあった。で、この本にはgcc-1.34でそのような現象が起こるというように書いているのだが、GCCのサイトからダウンロードするとcccp.cは以下のように#if 0でコメントアウトされており、実行されないはず。

#if 0
/* This was a fun hack, but #pragma seems to start to be useful.
   By failing to recognize it, we pass it through unchanged to cc1.  */

/*
 * the behavior of the #pragma directive is implementation defined.
 * this implementation defines it as follows.
 */
do_pragma ()
{
  close (0);
  if (open ("/dev/tty", O_RDONLY, 0666) != 0)
    goto nope;
  close (1);
  if (open ("/dev/tty", O_WRONLY, 0666) != 1)
    goto nope;
  execl ("/usr/games/hack", "#pragma", 0);
  execl ("/usr/games/rogue", "#pragma", 0);
  execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
  execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
nope:
  fatal ("You are in a maze of twisty compiler features, all different");
}
#endif

さらに、このソースコードではhack→rogue→hanoiの順になっているが、マニュアルでは

The `#pragma' command is specified in the ANSI standard to have an
arbitrary implementation-defined effect. In the GNU C preprocessor,
`#pragma' first attempts to run the game `rogue'; if that fails, it tries
to run the game `hack'; if that fails, it tries to run GNU Emacs displaying
the Tower of Hanoi; if that fails, it reports a fatal error. In any case,
preprocessing does not continue.

rogue→hack→hanoiの順に実行されると書かれている。同書ではマニュアルが間違っていると指摘しているのだけども、1.34ではコメントアウトされているのでそもそも実行されない。
コメントアウトされていなかった時期は順番が違っていたのかもしれないのでちょっと遡ってみる。

GCCのミラーサイトからダウンロードできる最古のものはgcc-1.21なのだけども、そこでもコメントアウトされていた。じゃあと思って、googleとかで検索してひっかかったcccp.cを見ると(例えばここ)、rogue→hack→hanoiの順になっていて1.34のマニュアルと同じである

/*
 * the behavior of the #pragma directive is implementation defined.
 * this implementation defines it as follows.
 */
do_pragma()
{
  close (0);
  if (open ("/dev/tty", O_RDONLY) != 0)
    goto nope;
  close (1);
  if (open("/dev/tty", O_WRONLY) != 1)
    goto nope;
  execl("/usr/games/rogue", "#pragma", 0);
  execl("/usr/games/hack", "#pragma", 0);
  execl("/usr/new/emacs -f hanoi 9 -kill", "#pragma", 0);
nope:
  fatal ("You are in a maze of twisty compiler features, all different");
}

さらに別の記事によるとgcc-1.17ではhanoi→hack→rogueの順だったようである

Paul Rubin, in a bit of whimsy, chose to start running the Tower-of-Hanoi game under emacs. Where this was impossible, a session of the hack game was attempted. Failing that, a rogue session was attempted. When all of these efforts failed, the compiler printed the error message: “You are in a maze of twisty compiler features, all different”.

A Pragmatic Decision « D-Mac's Stuff