c++ - switch-case 标签中的 C11 和常量表达式求值

标签 c++ c switch-statement constants constant-expression

关注这个问题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) .

  1. 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 :

  1. 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 the sizeof 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/

相关文章:

c++ - 启动服务时报错5

我们可以修改 const 变量的值吗?

c - 如果没有用户输入(在 C 中)

c - 这个 switch case 语法是什么意思?

javascript - 如何在 switch 语句中执行特定情况下的多个代码块?

c++ - 为什么两种乐趣都返回相同?

c++ - 在编译时连接模板中的编译时字符串?

c++ - 如何使我的 Qt 项目静态化 (.exe)

c - 如何加速以下代码以显着计算 CPU 上的 LBP?

PHP - 使用 for 循环而不是 switch 语句