最初のコードでは、両方の宣言をコンパイルする必要があります。GCCはすぐそこにあります。VisualC++コンパイラにはバグがあります。
そして2番目のコードでは、内部宣言はコンパイルされるべきではありません。GCCもそこにあり、VC++は間違っています。
GCCはどちらの場合も正しいです。
のようなコードは、構文の観点int a=a+100;
からint a(a+100);
は問題ありません。静的ストレージ期間と自動ストレージ期間のどちらで作成されたかによっては、未定義の動作が発生する可能性があります。
int a = a + 100; //well-defined. a is initialized to 100
//a on RHS is statically initialized to 0
//then a on LHS is dynamically initialized to (0+100).
void f()
{
int b = b + 100; //undefined-behavior. b on RHS is uninitialized
int a = a + 50; //which `a` is on the RHS? previously declared one?
//No. `a` on RHS refers to the newly declared one.
//the part `int a` declares a variable, which hides
//any symbol with same name declared in outer scope,
//then `=a+50` is the initializer part.
//since a on RHS is uninitialized, it invokes UB
}
上記の各宣言に関連するコメントをお読みください。
静的ストレージ期間の変数は、コンパイル時に静的にゼロに初期化され、初期化されている場合は、実行時にも動的に初期化されることに注意してください。ただし、自動保存期間を持つPODタイプの変数は、静的に初期化されません。
静的初期化と動的初期化の詳細については、以下を参照してください。