C++ switch语句表达式评估保证

mik*_*ikk 55 c++ standards language-lawyer

关于开关标准说明如下."当执行switch语句时,将评估其条件并与每个case常量进行比较."

这是否意味着条件表达式只评估一次和一次,并且每个编译器的标准都保证了它?

例如,当在switch语句头中使用函数时,会产生副作用.

int f() { ... }
switch (f())
{
    case ...;
    case ...;
}
Run Code Online (Sandbox Code Playgroud)

Bau*_*gen 37

我认为f只保证一次.

首先我们有

条件应为整数类型,枚举类型或类类型.

[6.4.2(1)](非整数的东西在这里不适用),和

作为表达式的条件的值是表达式的值

[6.4(4)].此外,

条件的值将简称为"条件",其中使用是明确的.

[6.4(4)]这意味着在我们的例子中,"条件"只是类型的普通值 int,而不是f.f仅用于查找条件的值.现在当控制到达switch语句时

评估其状况

[6.4.2(5)],即我们使用intf我们的"条件" 返回的值.最后条件(类型的值int,而不是f),是

与每个案例常数相比较

[6.4.2(5)].这不会f再次触发副作用.

所有报价均来自N3797.(还检查了N4140,没有区别)

  • @MattMcNabb它们是免费提供的吗?(对于这个问题,它们有什么不同吗?) (9认同)
  • 我认为OP的贪婪来自于句子的解析,因为"它的条件被评估(并与每个案例常量进行比较)"或"(它的条件被评估并与之比较)每个案例常量"与此无关.条件的输入. (2认同)

Per*_*xty 5

N4296

第10页第14段:

在与要评估的下一个全表达式相关联的每个值计算和副作用之前,对与全表达式相关联的每个值计算和副作用进行排序.

当我读到para的第一行时.10(上面):

完整表达式是不是另一个表达式的子表达式的表达式.

我必须相信switch语句的条件是一个完整的表达式,每个条件表达式都是一个完整的表达式(虽然执行时很简单).

A switch是一个声明而不是表达式(见6.4.2和许多其他地方).

因此,通过阅读,评估switch必须在评估case常数之前进行.

因为有很多要点归结为对规范的曲折阅读以得出明显的结论.

如果我同意审查该句,我会提出以下修正案(粗体):

执行switch语句时,每次执行 switch语句时都会对其条件求值 一次,并与每个case常量进行比较.

  • 如果你可以改写以避免双重否定它会有所帮助(特别是因为这两个部分是分开的). (2认同)