奔放な変数宣言よりスコープの先頭で変数が宣言されていた方がよいと思うのですが、しかし多くの場合、変数宣言の構文自体がないか、スコープの先頭に記述することを強制する文法になっていません(C89では変数宣言がスコープの先頭に制限されていますが、C99以降ではその限りではありません。また、int x; がコードのどこにでも書けそうな文法になっていることは変わりありません)。

ブロック構文がある言語では、ブロックを都度に開き、その中で使われる変数を宣言することで変数の寿命を明示できるため、個人で書く分にはただブロックを書けばよい話ではあるのですが(ただしJavaScriptでvarによる宣言をする場合、関数スコープに対して変数が定義されるのでその限りではないです)、もっと強制力のある方法があってよかった気がしています。

C89からC99への仕様緩和のいきさつは知らないのですが、何か深い考えのもとでスコープの途中での変数宣言が許されるようになったのでしょうか?

普通のプログラマとしての素直な感覚ではむしろその「奔放な変数宣言」の方が良いです。

コードを読む時は未知の識別子が出てくるたびに認知負荷が高まっていく訳ですからグローバル変数を始めとして内部から参照できる変数は少ないに越したことはありません。関数が1画面に収まるサイズならスコープの開始位置という決まった場所にあれば変数の宣言もすぐに確認できるというのは一理ありますがシリアスなコードを書いていれば1画面に収まらない関数というのはザラに出てきます。

特にC++のようにオブジェクトの生成自体に意味を持たせる事がある言語(例えばscoped_lockなど)においては宣言と生成を分ける方がアンチパターンでありRAII(Resource Acquisition Is Initialization)という言葉にも現れています。C99を策定する頃はJavaなども台頭してきておりそれらの良い所を適宜取り入れていくノリでスコープの先頭以外での宣言も許されたのだと思います。forループのカウンタのiなんかはループの外で触ってしまったら事故の元ですし、ループ外で触ったらコンパイルエラーで教えて欲しいです。スコープを細かく区切れるようにしてそこでの変数宣言は上に寄せたほうが良いというのは確かにそうだと思いますが、宣言が初期化を兼ねている方が読みやすいコードである以上は宣言位置をブロックの先頭に限定しないほうが柔軟な活用ができます。

そもそもがC89においてスコープの先頭でしか変数を宣言できなくしていたのは、その関数が使用するスタックのフレームサイズを早期に確定したいとかコンパイル中の識別子テーブルの実装を簡単にしたいといった実装依存の理由が強く、書かれるコードの品質の側面では特にメリットはありませんでした。

一方で「奔放な変数宣言」を許すと画面内のコードの塊の中で依存関係が完結しているケースにおいて読みやすくなりますしコピペしたらそのまま動くことも多いです。コードのコピペと言うと急に素人のやっつけ仕事っぽい印象がありますが、プロだって必要に応じてどんどんコピペを活用します。コード片のモジュール性が高い事の恩恵というのは日頃からデカいコードの上で仕事をしている人のほうが有り難みを感じるのではないかと思います。

2024/04/20投稿
Loading...
匿名で 熊崎 宏樹 さんにメッセージを送ろう

利用規約プライバシーポリシーに同意の上ご利用ください

Loading...