关注这个问题Why doesn't gcc allow a const int as a case expression? ,与 What promoted types are used for switch-case expression comparison? 基本相同或Is there any way to use a constant array with constant index as switch case label in C? .
从第一个链接开始,我尝试替换:
case FOO: // aka 'const int FOO = 10'
与:
case ((int) "toto"[0]): // can't be anything *but* constant
这给出:
https://ideone.com/n1bmIb -> https://ideone.com/4aOSXR = 在 C++ 中工作
https://ideone.com/n1bmIb -> https://ideone.com/RrnO2R = C 失败
我不太明白,因为“toto”字符串不能是任何东西,只能是一个常量,它甚至不是一个变量,它位于编译器内存的空白中。我什至没有玩C语言的“常量”模糊逻辑(它实际上代表“只读,非常量,你期望什么?”),问题是“数组访问”或“指针引用” "转换为常量表达式,该表达式在 C 中不求值,但在 C++ 中表现良好。
我希望使用这个“技巧”来使用 HASH_MACRO(str) 从键标识符生成唯一的大小写标签值,最终使编译器在由于发现相似标签值而发生冲突的情况下引发错误。
好吧,好吧,有人告诉我这些限制是为了简化语言工具(预处理、编译器、链接器),C 不是 LISP,但是您可以使用全功能的 LISP 解释器/编译器,而所需的大小只是相当于 C 语言,所以这不是借口。
问题是:C11 是否有一个“扩展”,只允许这个“toto”东西在 GCC、CLANG 和... MSVC 中工作?我不想走 C++ 路径(typedef 的前向声明不再起作用),并且因为嵌入的东西(因此时空扭曲的编译时哈希计算)。
是否有一种更‘宽容’和‘理解’更好的中间“C+”语言,例如-赞美上主-“枚举作为位域成员”,以及我们无法拥有的其他好东西(因为-现实标准像沙漠阳光下的蜗牛一样进化)?
#provemewrong、#changemymind、#norustplease
最佳答案
编译器在编译时是否知道它并不重要。 case
标签需要有一个整数常量表达式的值 (C11 6.8.4.2p3) .
- The expression of each
case
label shall be an integer constant expression and no two of the case constant expressions in the same switch statement shall have the same value after conversion. There may be at most one default label in a switch statement. (Any enclosed switch statement may have a default label or case constant expressions with values that duplicate case constant expressions in the enclosing switch statement.)
整型常量表达式的定义为in C11 6.6p6 :
- An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants,
sizeof
expressions whose results are integer constants,_Alignof
expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to thesizeof
or_Alignof
operator.
由于 "toto"
不是整型常量、枚举常量、字符常量、常量 sizeof
、_Alignof
表达式或浮点常量转换为整数;并且该列表是在标准的约束部分中指定的,编译器不得默默地传递该列表。 (即使符合标准的编译器仍然可以成功编译程序,但它必须将其诊断为约束违规。)
你可以使用什么是链式? :
将索引解析为字符常量,即
x == 0 ? 't'
: x == 1 ? 'o'
: x == 2 ? 't'
: x == 3 ? 'o'
这可以写入宏。
关于c++ - switch-case 标签中的 C11 和常量表达式求值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50510859/