わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

セミコロンで遊ぶ

 いきなりですが問題です.C言語で書かれた,以下のソースコードをご覧ください.

/* 1行目 */ #include <stdio.h>
/* 2行目 */
/* 3行目 */ int main(void)
/* 4行目 */ {
/* 5行目 */   printf("hello, world\n");
/* 6行目 */   return 0;
/* 7行目 */ }

 このソースコードの終わりに「;」を追加して,コンパイルエラーにならないのは,何行目でしょうか.
 さっそくですが解答です.コンパイルエラーにならないのは,3行目以外です.
 昨日の授業で,空文を解説しました.何も実行しない文のことで,C言語では「;」だけで表します.また,「for (初期化; 条件; 更新)」のうち,初期化・条件・更新を書かないのも,空文として扱われます.for文などで,よく{ }で括られるコードのところも,空文にできますが,これについては別記事にしたいと思います.
 授業前日23:59を提出期限とした予習課題*1を採点していて,C言語ソースコードには,その実用性はさておき,いろいろなところで「;」を書いて,エラーにならないことを知りました.
 たとえば冒頭のソースコードの最後に「;」を入れます.こうです.

/* 1行目 */ #include <stdio.h>
/* 2行目 */
/* 3行目 */ int main(void)
/* 4行目 */ {
/* 5行目 */   printf("hello, world\n");
/* 6行目 */   return 0;
/* 7行目 */ };

 ファイルに保存して,gccに-Wallオプションを付けてコンパイルしても,エラー・警告のメッセージが出ず,実行ファイルが作られました.実行すると,「hello, world」を出力してくれました.
 あらゆる関数の外,すなわちグローバルな領域で,空文が認められる,ということです.2行目に「;」を入れても同様にOKです.
 4~6行目の終わりに「;」を追加するのは,それが(main関数内の)空文となり,差し支えありません.
 1行目の最後は,どうでしょうか.

/* 1行目 */ #include <stdio.h>;
/* 2行目 */
/* 3行目 */ int main(void)
/* 4行目 */ {
/* 5行目 */   printf("hello, world\n");
/* 6行目 */   return 0;
/* 7行目 */ }

 これでコンパイルすると,警告メッセージが出ました.「warning: extra tokens at end of #include directive」です.なのですが実行ファイルは作られまして,これも,「hello, world」の出力になりました.
 3行目の最後に「;」を入れて,コンパイルすると,エラーとなりました.エラーメッセージは「expected identifier or '(' before '{' token」で,4行目の「{」を示しています.グローバルな領域で,複合文は,NGということですね*2

*1:来年度も出題する可能性があるので,具体的な問題の公開は差し控えます.

*2:3行目を「int main(void);int main(void)」に変更するのは,大丈夫です.セミコロンまでがmainの関数プロトタイプ宣言と見なされ,セミコロンのあとから7行目までが,その関数の定義となります.