じつはそんなに不思議な現象ではないのかも
このコードについて???? コンパイラの不思議 - goinger的日記を読んで軽く気になったので -fno-builtin でビルトインなものを消してみたりして考えみました。たどり着いたのは、C言語はファイル別にコンパイルするというだけの理由ではないかというもの。
たとえば、
int add(int a, int b) { return a + b; }
という関数を add.c として保存して、
void add();
main()
{
add();
}
を add.c とは別に test.c として作成する。
そのうえで
$ gcc test.c add.c
としてもエラーはでない。
コンパイルするときはプロトタイプ宣言のみしか見ていないからこれでも動くのでしょう。今回は、 puts() であると警告が入るので特別に感じたのではないかと考えます。