当前位置: 首页 > 知识库问答 >
问题:

是enum{a}e=1;有效的

栾弘新
2023-03-14

一个简单的问题:enum{a}e=1;有效吗?

换句话说:赋值是一种定义良好的行为,而枚举常量的值集中不存在这种行为吗?

演示:

$ gcc t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>

$ clang t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>

$ icc t0.c -std=c11 -pedantic -Wall -Wextra
t0.c(1): warning #188: enumerated type mixed with another type
# note: the same warning for enum { a } e = 0;

$ cl t0.c /std:c11 /Za /c
<nothing>

共有3个答案

阴高寒
2023-03-14

虽然根据202x工作草案,这在C中是有效的:

6.7.2.2/4每个枚举类型应与char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但应能够表示枚举所有成员的值

由于更强的“兼容类型”要求,指出同样的情况不适用于C可能很有趣,其中“C样式”没有固定基础类型的无作用域枚举与C有细微的区别:这是一个关键的区别。

如果我们在C中考虑类似的语法上的例子:

// C++ does not allow implicit conversion _from_ an integer type
// _to_ an unscoped enum with no explicit underlying type, so we'll
// need to resort to explicit conversions for a similar example
enum E { a } e = static_cast<E>(2);  // #1

// or ...
enum E { a } e = E(2);

根据[dcl.enum]/7,

对于基础类型为固定的枚举,枚举的值是基础类型的值。否则,枚举的值是由一个假设的整数类型表示的值,该类型的宽度最小为M,这样所有枚举数都可以被表示。足以容纳枚举类型的所有值的最小位字段的宽度为M。可以定义一个枚举,该枚举的值不是由其任何枚举数定义的。如果枚举数列表为空,则枚举的值就好像枚举有一个值为0的枚举数一样。

和[expr.static.cast]/10:

整型或枚举类型的值可以显式转换为完整的枚举类型。如果枚举类型具有固定的基础类型,则在必要时,首先通过整数转换将值转换为该类型,然后再转换为枚举类型。如果枚举类型没有固定的基础类型,则如果原始值在枚举值([dcl.enum])的范围内,则该值将保持不变,否则,该行为将未定义。浮点类型的值也可以显式转换为枚举类型。生成的值与将原始值转换为枚举的基础类型([conv.fpint]),然后再转换为枚举类型相同。

上面的#2可能(取决于E的实现定义的基础类型)导致未定义的行为(在CWG 1766之前是未指定的行为),在概念上可能导致有符号整数溢出(即UB)。

宋弘壮
2023-03-14

我在本C11标准草案中找不到任何禁止分配给enum类型(如您的类型)的参考(另一个答案中引用的C18标准使用了基本相同的措辞)。

然而,C11草案确实在附录I——常见警告中提供了这一点:

1.

但是,建议的警告同样适用于enum{a}e=0;这样的赋值,其中RHS的值对应于一个有效的枚举常量,但它实际上既不是类型的枚举常量,也不是枚举的类型。

公羊招
2023-03-14

来自6.7.2.2C18标准:

每个枚举类型应与char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但应能够表示枚举所有成员的值。

所以是enum{a}e=1 是有效的e是一个“整数”类型,因此它可以接受值11不作为枚举值存在这一事实不成问题。枚举成员只为一些可能的值提供方便的标识符。

 类似资料:
  • The licenses for most software are designed to take away your freedom to share and change it. By contrast, the gnu General Public License is intended to guarantee your freedom to share and change free

  • The licenses for most software are designed to take away your freedom to share and change it. By contrast, the gnu General Public License is intended to guarantee your freedom to share and change free

  • The licenses for most software are designed to take away your freedom to share and change it. By contrast, the gnu General Public License is intended to guarantee your freedom to share and change free

  • 尽管我们已经实现了购物车的基本功能,不过我们还有许多功能需要处理。一开始,我们要识别出用户是何时添加多个相同商品至购物车的。而且,当错误发生时我们也要保证购物车可以友好地反应,以及向客户或系统管理员通知相应信息。 迭代 E1:创建更智慧的购物车 由于我们需要统计购物车中的每件商品数量,所以我们需要修改 line_items 表。不过我们已经使用过迁移了,就像 64 页的情况一样,我们已经应用过迁移

  • N4527 5.20【expr.const】p5 常量表达式是glvalue核心常量表达式,其值是指常量表达式(定义如下)的允许结果实体,或者是prvalue核心常量表达式,其值是对象,其中,对于该对象及其子对象: -引用类型的每个非静态数据成员引用一个实体,该实体是常量表达式的允许结果,并且 -如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址、超过此类对象结尾的地址(5.7)

  • 类似于这个针对javascript的问题,它已经为各种不同的语言衍生出了许多副产品。我很好奇,在PHP中是否有以下情况: