Help us understand the problem. What is going on with this article?

C言語での変数宣言ってどこに書けるのさ?

More than 1 year has passed since last update.

Where have all the declarations gone?

某日某所、3人のプログラマの雑談より:

Xさん「C言語って関数先頭でしか変数宣言できないから面倒だよねぇ。」
Yさん「何いってんすか、{}ブロックの先頭ならいつでも変数宣言できるしょ。」
Zさん「いやいや、イマドキのC言語ならどこでも変数宣言できますから。」

さて3名のプログラマのうち、誰の主張が正しいのでしょう?もしかして、過去には彼らが言うような制限も実在したのでしょうか?これってトリビアになりませんか?

このトリビアの種、つまりこういうことになります:
「C言語で変数宣言を配置できる場所は ○○」

"C99"(1999年) ~ 現在まで

実際にプログラミング言語Cの言語仕様(Language Specification)を調べてみた。

2019年6月現在のC言語仕様は国際標準規格 ISO/IEC 9899:2018 として定義される。同規格はこれまでに 2011年、1999年 それぞれで改訂が行われており、ISO/IEC 9899:1999 における構文(Syntax)定義は次のようになっている。

compound-statement:
    { block-item-listopt }
block-item-list:
    block-item
    block-item-list block-item
block-item:
    declaration
    statement

compound-statement(複合文) は{}で囲われたブロックを表し、 declaration(宣言) が変数宣言に対応する。この構文定義からは、compound-statement(複合文) 中には declaration(宣言) と statement(文) とを任意順序で記述可能 であると読み取れる。

Zさん「いやいや、イマドキのC言語ならどこでも変数宣言できますから。」

つまり、Z氏の主張は 1999年以降のモダンなC言語 を指すと考えられる。

"K&R C 1st Ed."(1978年) ~ "ANSI C"(1999年以前)

プログラミング言語Cは1989年に ANSI C として初めて標準化されたが、それ以前からC言語の生みの親 ブライアン・カーニハン(Brian W. Kernighan)デニス・リッチー(Dennis M. Ritchie) 両名の名を冠した 書籍 "K&R C" として言語仕様(相当)のリファレンスが存在していた。

書籍 "K&R C" は 第1版(1st Ed.) から 第2版(2nd Ed.) の間で大きく内容改訂されているが、ここでは1978年刊行の K&R C 第1版 より構文定義を引用する。

compound-statement:
    { declaration-listopt statement-listopt }
declaration-statement:
    declaration
    declaration declaration-list
statement-statement:
    statement
    statement statement-list

この構文定義からは、compound-statement(複合文) 中では 複数 declaration(宣言) に続く 複数 statement(文) の順序に限って記述可能 であると読み取れる。

Yさん「何いってんすか、{〜}ブロックの先頭ならいつでも変数宣言できるしょ。」

つまり、Y氏の主張は 1978年以降かつ1999年より前のレガシーなC言語 を指すと考えられる。和暦でいうと 昭和53年以降かつ平成11年より前 である。

"C Reference Manual"(1975年)

最後に、X氏の主張を検証してみよう。

Xさん「C言語って関数先頭でしか変数宣言できないから面倒だよねぇ。」

書籍 "K&R 1st Ed." 時点でも 任意の compound-statement(複合文) 先頭において変数宣言が可能であったことから、X氏の言にあるC言語は実在しないのだろうか?

ここでX氏の名誉のために、プログラミングC言語の言語仕様に類する文書としては最古のものと考えられる、オペレーティングシステム 6th Edition Unix(UNIX v6) 付属のC言語コンパイラ・リファレンスマニュアル "C Reference Manual" まで遡ってみる。

compound-statement:
    { statement-list }
statement-list:
    statement
    statement statement-list

function-definition:
    type-specifieropt function-declarator function-body
function-body:
    type-decl-list function-statement
function-statement:
    { declaration-listopt statement-list }

この構文定義からは、compound-statement(複合文) 中では 複数 statement(文) しか許容されず、function-body(関数本体) でのみ 複数 declaration(宣言) に続く 複数 statement(文) の順序に限って記述可能 であると読み取れる。

Xさん「C言語って関数先頭でしか変数宣言できないから面倒だよねぇ。」

つまり、X氏の主張は "C言語"生誕(1972年)から1975年頃の古代C言語 を指すと解釈するのが妥当であろう。X氏の名誉は守られたのだ。

まとめ

     │/
  / ̄\●─
 /~~⊂ニ⊃
/   / ̄\
~~~/   \
こうしてこの世界にまた一つ
新たなトリビアが生まれた
yohhoy
「なんにも知らないって、すっごくしあわせ!」--スヌーピー
https://yohhoy.hatenadiary.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away