LinuxカーネルやGNOMEなどのオープンソースCプロジェクトでC99混合宣言とコードがまだ使用されていないのはなぜですか?
宣言とコードが混在しているのが本当に好きです。コードが読みやすくなり、変数のスコープを可能な限り狭く制限することで、見づらいバグを防ぐことができるからです。これは、Google forC++によって推奨されています。
たとえば、Linuxには少なくともGCC 3.2が必要であり、GCC3.1はC99混合宣言とコードをサポートしています。
LinuxカーネルやGNOMEなどのオープンソースCプロジェクトでC99混合宣言とコードがまだ使用されていないのはなぜですか?
宣言とコードが混在しているのが本当に好きです。コードが読みやすくなり、変数のスコープを可能な限り狭く制限することで、見づらいバグを防ぐことができるからです。これは、Google forC++によって推奨されています。
たとえば、Linuxには少なくともGCC 3.2が必要であり、GCC3.1はC99混合宣言とコードをサポートしています。
スコープを制限するために宣言とコードを混在させる必要はありません。できるよ:
{
int c;
c = 1;
{
int d = c + 1;
}
}
C89で。これらのプロジェクトが混合宣言を使用していない理由については(これが真実であると仮定して)、「壊れていない場合は修正しないでください」というケースである可能性が最も高いです。
これは古い質問ですが、慣性がこれらのプロジェクトのほとんどがまだANSIC宣言ルールを使用している理由であることを示唆します。
ただし、有効なものからばかげたものまで、他にも多くの可能性があります。
移植性。多くのオープンソースプロジェクトは、衒学的なANSICがソフトウェアを作成するための最も移植性の高い方法であるという前提の下で機能します。
年。これらのプロジェクトの多くはC99仕様よりも前のものであり、作成者は一貫したコーディングスタイルを好む可能性があります。
無知。以前のC99を提出したプログラマーは、宣言とコードが混在していることの利点を認識していません。(別の解釈:開発者は潜在的なトレードオフを十分に認識しており、宣言とステートメントの混合は努力する価値がないと判断します。私は非常に同意しませんが、2人のプログラマーが何かに同意することはめったにありません。)
FUD。プログラマーは、混合宣言とコードを「C ++ ism」と見なし、その理由でそれを嫌います。
Linuxカーネルを書き直して、パフォーマンスを向上させない外観上の変更を加える理由はほとんどありません。
コードベースが機能している場合、外観上の理由でコードベースを変更するのはなぜですか?
カーネル コードのスタイル ガイドで、これに対する禁止事項を覚えていません。ただし、関数はできるだけ小さくし、1 つのことだけを行うべきであると述べています。これは、宣言とコードの混合がまれである理由を説明します。
小さな関数では、スコープの先頭で変数を宣言することは、一種のIntroitとして機能し、すぐ後に何が起こるかについて何かを伝えます。この場合、変数宣言の動きは非常に制限されているため、効果がないか、いわば客引きを群集に押し込んで機能に関する情報を隠すのに役立つ可能性があります。王が部屋に入る前に到着が宣言されたのには理由があります。
変数とコードを混在させて読み取り可能な関数である OTOH は、おそらく大きすぎます。これは、関数の一部のセクションを個別の関数に抽象化する必要がある (そして を宣言しstatic
て、オプティマイザがそれらをインライン化できるようにする) 必要があるという兆候の 1 つです (入れ子が多すぎるブロック、インライン コメントなどと同様)。
関数の先頭に宣言を保持するもう 1 つの理由: コード内のステートメントの実行順序を変更する必要がある場合、コードの途中で宣言された変数のスコープが、コードの途中で宣言されているため、変数をそのスコープの外に移動する可能性があります。インデントでは明らかではありません (ブロックを使用してスコープを表示しない限り)。これは簡単に修正できるので単なる煩わしさですが、新しいコードはしばしばこの種の変換を受け、煩わしさが累積する可能性があります。
もう 1 つの理由: 次のように、変数を宣言して関数からエラー リターン コードを取得したくなるかもしれません。
void_func();
int ret = func_may_fail();
if (ret) { handle_fail(ret) }
完全に合理的なことです。しかし:
void_func();
int ret = func_may_fail();
if (ret) { handle_fail(ret) }
....
int ret = another_func_may_fail();
if (ret) { handle_other_fail(ret); }
おっと!ret
が 2 回定義されています。「それで?二度目の宣言を外して」あなたは言う。しかし、これによりコードが非対称になり、リファクタリングの制限が増えます。
もちろん、私は自分で宣言とコードを混在させています。それについて独断的になる理由はありません(そうでなければ、あなたのカルマがあなたの教義を超えてしまうかもしれません:-)。しかし、付随する問題が何であるかを知っておく必要があります。
メリットはありません。関数の先頭ですべての変数を宣言する (pascal のように) ほうがはるかに明確です。C89 では、各スコープの先頭で変数を宣言することもできます (ループ内の例)。これは実用的で簡潔です。
多分それは必要ではないかもしれません、多分分離は良いですか?私はC++でそれを行います。C++にもこの機能があります。
このようにコードを変更する理由はなく、C99 はまだコンパイラによって広くサポートされていません。それは主に携帯性に関するものです。