const enum Alpha{
X=9,
Y=5,
Z=2
}p;
int main(){
enum Alpha a,b;
a= X;
b= Z;
p = X;
p = Y;
printf("%d",a+b-p);
return 0;
}
MSVCコンパイラでp=Xおよびp=Yが許可されているのはなぜですか?このコードは6を出力します。初期化時にconst値を割り当ててはいけませんか?
const enum Alpha{
X=9,
Y=5,
Z=2
}p;
int main(){
enum Alpha a,b;
a= X;
b= Z;
p = X;
p = Y;
printf("%d",a+b-p);
return 0;
}
MSVCコンパイラでp=Xおよびp=Yが許可されているのはなぜですか?このコードは6を出力します。初期化時にconst値を割り当ててはいけませんか?
これはコンパイラ自体のバグです。話の終わり。
実際、あなたの小さなコードはコンパイラーに2つのバグを示しています。最初のバグはここにあります:
const enum Alpha{
X=9,
Y=5,
Z=2
}p; //declaration of p is ill-formed!
の宣言は形式が正しくないため、宣言されているが初期化さp
れていないため、コンパイラはこのコードを拒否する必要があります。整形式にするには、スカラー(およびポッド)タイプを初期化する必要があります。p
const
const
const Alpha q; //ill-formed (same case is with p in your code)
const Alpha r = X; //well-formed
詳細で詳細な説明については、以下を参照してください。
確かに、バグのように見えます。
まず、グローバルconst
オブジェクトは定義時に初期化する必要があり、デフォルトの初期化は列挙型のオプションではありません。C++11規格の8.5/6項によると:
デフォルトで-タイプTのオブジェクトを初期化するということは、次のことを意味します。
— Tが(おそらくcv修飾された)クラスタイプの場合(第9節)、Tのデフォルトコンストラクターが呼び出されます(Tにアクセス可能なデフォルトコンストラクターがない場合、初期化は不正な形式になります)。
— Tが配列型の場合、各要素はデフォルトで初期化されます。
—それ以外の場合、初期化は実行されません。
プログラムがconst修飾型Tのオブジェクトのデフォルトの初期化を要求する場合、Tはユーザー提供のデフォルトコンストラクターを持つクラス型でなければなりません。
次に、const
初期化後にオブジェクトを割り当てることはできません。
これがコンパイラのバグであるというコンセンサスに一致するように編集されました。
これは、コンパイラがpが型Alpha
であり、ではないと誤って判断するために機能しconst Alpha
ます。これを次のように書き直すと
enum Alpha{....
} const p;
コンパイラは、定数が初期化されていないことを正しく文句を言います。
error C2734: 'p' : const object must be initialized if not extern
error C3892: 'p' : you cannot assign to a variable that is const
定数を割り当てると、
enum Alpha{....
} const p = Y;
pへの割り当てを削除すると、すべてが期待どおりにコンパイルおよび動作します。