編集:元の回答(以下)を書いたとき、これに気づきませんでした。投稿したコードは違法であり、未定義の動作を引き起こします。問題のある行は次のとおりです。
char *x = strchr(x,' ');
ここで、呼び出しx
内のは、囲んでいるスコープで定義されたものを参照するのではなく、同じ行で以前に定義されたものを参照します。したがって、その行は初期化されていない変数から読み取るため、未定義の動作が発生します。C++ 標準から、strchr
x
x
§3.3.2/1 [basic.scope.pdecl]
名前の宣言
のポイントは、完全な宣言子 (第 8 節) の直後で、初期化子(存在する場合) の前です。ただし、以下に示す場合を除きます。[ 例:
int x = 12;
{ int x = x; }
ここで、2 番目の x は独自の (不確定な) 値で初期化されます。—終わりの例]
以下の例の対応する行が次のように変更された場合、GCC は文句を言います。
int x = 21 + x; // generates "warning: x is used uninitialized in this function"
またstrchr
、VS2012 で例を複製すると、次の警告が生成されます (at/W1
以上):
warning C4700: uninitialized local variable 'x' used
元の答えは次のとおりです(完全に正確ではありません):
コードに違法性はありません。中括弧を追加して新しいスコープを導入しました。それらの変数名が外側のスコープで以前に定義されていたとしても、新しいスコープ内で変数を定義できます。
新しい定義の後の変数へのすべての参照は、ローカル変数の有効期間が終了するまで、外側のスコープ内の変数ではなくローカル変数を参照します。次のコードは、GCC でコンパイルした場合でも警告を生成しません。-pedantic -Wall -Wextra
#include <iostream>
int main()
{
int x = 42;
{
std::cout << x << '\n';
int x = 21;
std::cout << x << '\n';
}
std::cout << x << '\n';
}
出力:
42
21
42
lint または別の静的分析ツールがそのようなものを選択するかどうかもわかりません。合法ですが、お勧めできません。