开关案例标签中的C11和常量表达式求值 [英] C11 and constant expression evaluation in switch-case labels

查看:124
本文介绍了开关案例标签中的C11和常量表达式求值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

遵循此问题为什么不gcc允许const int作为大小写表达式吗?,基本上与。是否有任何方法可以将具有恒定索引的常量数组用作C的转换案例标签?。 p>

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

following this question Why doesn't gcc allow a const int as a case expression?, basically the same as What promoted types are used for switch-case expression comparison? or Is there any way to use a constant array with constant index as switch case label in C?.

From the first link, I tried to replace :

with:

with :

哪个给了:

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

Which gives :

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

https://ideone.com/n1bmIb -> https://ideone.com/4aOSXR = works in C++

我不太了解,因为 toto字符串不能是任何东西,但是一个常量,它甚至不是变量,它位于编译器内存的空白中。我什至没有在使用C语言的 const模糊逻辑(它实际上代表只读,不是常数,您期望什么?),问题是数组访问或指针引用

https://ideone.com/n1bmIb -> https://ideone.com/RrnO2R = fails in C

我希望使用此技巧来使用HASH_MACRO(str)

I don't quite understand since the "toto" string can't be anything but a constant one, it isn't even a variable, it lies in the void of the compiler memory. I'm not even playing with the 'const' fuzzy logic of the C language (that really stands for "read-only, not constant, what did you expect?"), the problem is either "array access" or "pointer referencing" into a constant expression that do not evaluate in C, but do quite well in C++.

好,好吧,我当时是因为发现了相似的标签值而最终导致编译器在发生冲突的情况下引发错误。

I expected to use this "trick" to use a HASH_MACRO(str) to generate unique case labels values from a key identifier, leaving eventually the compiler to raise an error in case of collision because of similar label values found.

告诉我们这些限制是为了简化语言工具(preproc,编译器,链接器)和C并不是没有LISP,但是您可以使用功能齐全的LISP解释器/编译器,而价格仅为C等效语言的一小部分,因此这不是借口。

OK, ok, I was told these restrictions were made to simplify language tooling (preproc, compiler, linker) and C ain't no LISP, but you can have full featured LISP interpreter/compilers for a fraction of the size of a C equivalent, so that's no excuse.

问题是:C11是否有扩展名,仅允许该 toto项在GCC,CLANG和... MSVC中工作?我不想走C ++路径(typedef的前向声明不再起作用),而且因为嵌入的东西(因此需要进行编译时哈希计算来实现时空失真)。

Question is : is there an "extension" to C11 that just allows this "toto" thingy to work in GCC, CLANG and... MSVC ? I don't want to go the C++ path (typedef's forward declarations don't work anymore) and because embedded stuff (hence the compile-time hash computation for space-time distortion).

是否存在一种中间的 C +语言,它更宽容,并且理解的语言嵌入得更好,例如-Praise the Lords-枚举为位域成员,除了其他我们无法拥有的(因为像蜗牛在沙漠的阳光下进化的非现实标准)?

Is there an intermediary "C+" language that is more 'permissive' and 'understand' embedded a little better, like -Praise the Lords- "enums as bitfield members", among nice other things we cannot have (because of out-of-reality standards evolving like snails under a desert sun) ?

#provemewrong,#changemymind,#norustplease

#provemewrong, #changemymind, #norustplease

推荐答案

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

It doesn't matter whether or not it could be known to the compiler at compile time. The case label needs to have a value that is an integer constant expression (C11 6.8.4.2p3).



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

  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.)


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

And the definition of an integer constant expression is in C11 6.6p6:



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

  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 表达式或浮点常量转换为整数;并且该列表是在标准的约束部分中指定的,因此编译器绝不能静默传递此列表。 (即使合格的编译器仍然可以成功编译程序,但是它必须将其诊断为约束冲突。)

Since "toto" is none of integer constants, enumeration constants, character constants, constant sizeof, _Alignof expressions or floating point constant cast to an integer; and that list was specified in the constraints section of the standard, the compiler must not pass this silently. (Even a conforming compiler may still successfully compile the program, but it must diagnose this as a constraint violation.)

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

What you can use is chained ? : to resolve the index to a character constant, i.e.

  x == 0 ? 't' 
: x == 1 ? 'o'
: x == 2 ? 't'
: x == 3 ? 'o'

可以将其写入宏。

这篇关于开关案例标签中的C11和常量表达式求值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆