C11和开关盒标签中的常量表达式评估

Koc*_*ise -5 c c++ constants switch-statement constant-expression

关注这个问题为什么gcc不允许将const int作为case表达式?,什么促销类型用于switch-case表达式比较基本相同或者有没有办法在C中使用具有常量索引的常量数组作为开关案例标签?.

从第一个链接,我试图替换:

case FOO:                       // aka 'const int FOO = 10'
Run Code Online (Sandbox Code Playgroud)

用:

case ((int) "toto"[0]):         // can't be anything *but* constant
Run Code Online (Sandbox Code Playgroud)

这使 :

https://ideone.com/n1bmIb - > https://ideone.com/4aOSXR =在C++中工作

https://ideone.com/n1bmIb - > https://ideone.com/RrnO2R = C失败

我不太明白,因为"TOTO"字符串不能是任何东西,但一个常数之一,它甚至不是一个变量,它位于编译器内存的空白.我甚至没有玩C语言的'const'模糊逻辑(它实际上代表"只读,不是常数,你期望什么?"),问题是"数组访问"或"指针引用" "进入一个不用C语言评估的常量表达式,但在C++中做得很好.

我希望使用这个"技巧"来使用HASH_MACRO(str)从密钥标识符生成唯一的case标签值,最终使编译器在发生冲突时引发错误,因为找到了类似的标签值.

好的,好的,我被告知这些限制是为了简化语言工具(preproc,编译器,链接器)而C不是没有LISP,但你可以拥有全功能的LISP解释器/编译器,其大小只相当于C等价物的一小部分,所以这不是借口.

问题是:C11是否有"扩展",只允许这个"toto"东西在GCC,CLANG和...... MSVC中工作?我不想去C++路径(typedef的前向声明不再起作用)和嵌入式东西(因此编译时哈希计算用于时空失真).

是否有一种中间的"C +"语言更加"宽容"和"理解"嵌入更好一点,比如 - 赞美领主 - "作为位域成员的枚举",以及我们不能拥有的其他很好的东西(由于以外的原因)现实标准像沙漠太阳下的蜗牛一样演变?

#provemewrong,#changemymind,#norustplease

Ant*_*ala 6

在编译时编译器是否可以知道它并不重要.的case标签需要有一个值,该值是一个整数常量表达式 (C11 6.8.4.2p3) .

  1. 每个case标签的表达式应为整数常量表达式,并且同一switch语句中的两个case常量表达式在转换后不应具有相同的值.switch语句中最多可能有一个默认标签.(任何封闭的switch语句都可以有一个默认的标签或case常量表达式,其值可以在封闭的switch语句中复制case常量表达式.)

并且整数常量表达式的定义在C11 6.6p6中:

  1. 整数常量表达式应具有整数类型,并且只能具有整数常量的操作数,枚举常量,字符常量,sizeof结果为整数常量的_Alignof表达式,表达式以及作为强制转换的直接操作数的浮点常量.整数常量表达式中的转换运算符只能将算术类型转换为整数类型,除非作为sizeof_Alignof运算符的操作数的一部分.

因为"toto"没有整数常量,枚举常量,字符常量,常量sizeof,_Alignof表达式或浮点常量强制转换为整数; 并且该列表是在标准的约束部分中指定的,编译器不能以静默方式传递它.(即使是符合标准的编译器仍然可以成功编译程序,但它必须将其诊断为违反约束.)


您可以使用链接? :来将索引解析为字符常量,即

  x == 0 ? 't' 
: x == 1 ? 'o'
: x == 2 ? 't'
: x == 3 ? 'o'
Run Code Online (Sandbox Code Playgroud)

这可以写入宏.

  • 你可以接受C标准委员会. (4认同)

归档时间:

查看次数:

433 次

最近记录:

7 年,6 月 前