このコードを考えてみましょう:
void foo()
{
goto bar;
int x = 0;
bar: ;
}
へのジャンプが変数の初期化をバイパスするため、GCCとClang はそれを拒否しbar:
ます。MSVCはまったく文句を言いません(x
after を使用bar:
すると警告が表示されます)。
同じことをaで行うことができますswitch
:
void foo()
{
switch (0)
{
int x = 0;
case 0: ;
}
}
3つのコンパイラすべてがエラーを出力するようになりました。
これらのスニペットの形式は不適切ですか?または、それらはUBを引き起こしますか?
以前はどちらも形式が正しくないと思っていましたが、標準の魅力的な部分を見つけることができません。[stmt.goto]は、このことについて何も言われ、どちらもしないん[stmt.select] 。
標準ではありませんが、ここでいくつかの情報を見つけることができます:en.cppreference.com/w/cpp/language/goto 特に:「制御の転送が自動変数のスコープに入る場合(たとえば、宣言を飛び越えて移動した場合)声明)、プログラムは悪いが形成される(コンパイルすることはできません)、しない限り...」
—
idclev 463035818
/permissive-
MSVCにフラグを追加すると、メッセージも表示されます。ただし、そのフラグのないMSVCの動作が明確に定義されているかどうかはわかりません(そうだとすれば、そうでないとなぜ許可されるのでしょうか?)。
@walnut 「そうでなければ、なぜそれを許可するのか」おそらく下位互換性のためか、標準をあまり気にしません。すべての主要なコンパイラは、デフォルト設定では標準に準拠していません。
—
HolyBlackCat
x
ジャンプ後に使用する場合、問題はより簡単になります。