【问题标题】:MSVC const enum typeMSVC 常量枚举类型
【发布时间】:2023-03-06 15:20:01
【问题描述】:
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 值,以后再也不分配?

【问题讨论】:

  • 将 a 分配给 p 有效吗?
  • 是的,在这种情况下输出为 2
  • 请注明您的确切编译器版本。
  • 带有 SP1 的 VS2010 编译器

标签: c++


【解决方案1】:

这是编译器本身的一个错误。故事结束。

事实上,您的小代码在编译器中显示了两个错误。第一个错误就在这里:

const enum Alpha{
    X=9,
    Y=5,
    Z=2
}p;    //declaration of p is ill-formed!

p 的声明格式不正确,因此编译器应拒绝此代码,因为 p 声明为 const 但未初始化。必须初始化 const 标量(和 pod)类型才能形成良好的格式:

const Alpha q;      //ill-formed (same case is with p in your code)
const Alpha r = X;  //well-formed

有关详细和广泛的解释,请参见:

【讨论】:

  • 该死,我发现了一个错误 :( 谢谢
  • Alpha 不是 POD 吗?真的吗?
  • @LightnessRacesinOrbit:那错字。
  • 这在 VS2013 上仍然可以正常工作。你们确定这是一个错误吗?
  • 更新:已在VS2013中修复,这是一个错误
【解决方案2】:

确实看起来像一个错误。

首先,全局const对象在定义时必须初始化,default-initialization不是枚举类型的选项。根据 C++11 标准第 8.5/6 段:

默认初始化 T 类型的对象意味着:

——如果 T 是一个(可能是 cv 限定的)类类型(第 9 条),则调用 T 的默认构造函数(并且 如果 T 没有可访问的默认构造函数,则初始化是非良构的);

——如果 T 是一个数组类型,每个元素都是默认初始化的;

——否则,不执行初始化。

如果程序要求对 const 限定类型 T 的对象进行默认初始化,则 T 应为具有用户提供的默认构造函数的类类型

其次,const对象初始化后无法赋值。

【讨论】:

    【解决方案3】:

    已编辑以符合共识,即这是一个编译器错误。

    这是因为编译器错误地认为 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 的赋值,一切都按预期编译和工作。

    【讨论】:

    • “这是可行的,因为 p 的类型是 Alpha 而不是 const Alpha。这是错误的。 p 的类型是 const Alpha,因为 const 适用于变量,而不是枚举定义。另外,const Alpha pAlpha const p 是完全一样的东西!
    • 我不是语言律师。我会把它留给专家。
    • 您无需成为“语言律师”或“专家”即可知道这一点。对 C++ 声明有一个很好的理解就绰绰有余了。
    • 还有一点关于 PODness 和默认构造函数的内容。我无法检查这是否应该编译,但 MSVC 可以,enum Alpha {...} const p = Alpha(); 并不清楚(至少对我而言)这与 enum Alpha{...} p; 不同
    • enum Alpha {...} const p = Alpha(); 绝对没问题,因为您正在初始化p。第二个例子enum Alpha {...} p;也可以,因为p在这种情况下不是const,所以你可以不初始化。
    猜你喜欢
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 2015-08-21
    • 2014-08-20
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多