ストロウストルップのC++ プログラミング言語: 特別版 (第 3 版)Stroustrup 氏は、制御文の条件文での変数の宣言と初期化は許可されているだけでなく、推奨されていると書いています。変数のスコープが、必要なスコープのみに縮小されるため、推奨されていると書いています。つまり、次のようになります...
if ((int i = read(socket)) < 0) {
// handle error
}
else if (i > 0) {
// handle input
}
else {
return true;
}
...は、優れたプログラミング スタイルと実践です。変数は、必要なステートメントi
ブロックの間だけ存在し、その後はスコープ外になります。if
ただし、このプログラミング言語の機能は、g++ (バージョン 4.3.3 Ubuntu 固有のコンパイル) ではサポートされていないようです。これは私にとって驚きです。おそらく、これをオフにするフラグ (呼び出したフラグは と-g
)を付けて g++ を呼び出しているだけなのでしょう-Wall
。私のバージョンの g++ では、これらのフラグを付けてコンパイルすると、次のコンパイル エラーが返されます。
socket.cpp:130: error: expected primary-expression before ‘int’
socket.cpp:130: error: expected `)' before ‘int’
さらに調べてみると、これをサポートしていないコンパイラを使用しているのは私だけではないようです。また、この質問正確には、その言語で標準とされている構文は何か、また、どのコンパイラがそれを使用してコンパイルするかについてです。
そこで疑問になるのは、どのコンパイラがこの機能をサポートし、コンパイルするにはどのフラグを設定する必要があるかということです。これは、特定の標準にはあって、他の標準にはないという問題なのでしょうか?
また、単なる好奇心ですが、これは良いスタイルだという Stroustrup の意見に、一般的には同意しているのでしょうか? それとも、これは言語の作成者が、その言語のコミュニティによって必ずしもサポートされていないアイデアを思いついた状況なのでしょうか?
ベストアンサー1
if
ネストされたブロックの制御部分で変数を宣言することは許可されていますが、およびの場合while
、変数は条件として解釈される数値またはブール値に初期化される必要があります。できないより複雑な表現に含めることができます。
あなたが示した特定のケースでは、残念ながら遵守する方法を見つけることができないようです。
個人的には、ローカル変数をコード内の実際の有効期間にできるだけ近づけておくのが良い習慣だと思います。C から C++ に、または Pascal から C++ に切り替えると、それが衝撃的に聞こえるかもしれませんが、私たちはすべての変数を 1 か所で確認することに慣れていました。慣れると、より読みやすくなり、宣言を見つけるために他の場所を探す必要がなくなります。さらに、その時点より前には使用されていないことがわかります。
編集:
そうは言っても、1 つのステートメントに多くのものを混ぜるのは良い方法ではないと思いますし、これは共通の意見だと思います。変数に値を適用し、それを別の式で使用する場合、両方の部分を分離することで、コードが読みやすくなり、混乱が少なくなります。
したがって、次のようにするのではなく:
int i;
if((i = read(socket)) < 0) {
// handle error
}
else if(i > 0) {
// handle input
}
else {
return true;
}
私は以下を希望します:
int i = read(socket);
if(i < 0) {
// handle error
}
else if(i > 0) {
// handle input
}
else {
return true;
}