对于c和c++中的同一程序,当我们使用常量整数变量作为大小写标签时,它只在c++中有效,而在c中无效;当我们使用常量整数数组成员作为大小写标签时,它在c和c++中都无效。 这种行为的主要原因是什么?
//for c
#include <stdio.h>
int main()
{
const int a=90;
switch(90)
{
case a://error : case label does not reduce to an integer constant
printf("error");
break;
}
const int arr[3]={88,89,90};
switch(90)
{
case arr[2]://error : case label does not reduce to an integer constant
printf("Error");
break;
}
}
//for c++
#include <stdio.h>
int main()
{
const int a=90;
switch(90)
{
case a:
printf("No error");
break;
}
const int arr[3]={88,89,90};
switch(90)
{
case arr[2]://error 'arr' cannot appear in a constant-expression
printf("Error");
break;
}
}
这种行为的主要原因是什么?
主要原因是2018年C标准在6.8.4.2 3中对case
标签规定“每个case
标签的表达式应为整数常量表达式……”,并在6.6 6中定义了整数常量表达式:
整数常量表达式应具有整数类型,且仅具有整数常量,枚举常量,字符常量,结果为整数常量的sizeof
表达式,_alignof
表达式以及作为强制转换的直接操作数的浮动常量的操作数。 整数常量表达式中的强制转换运算符只能将算术类型转换为整数类型,除非作为操作数的一部分转换为sizeof
或_alignof
运算符。
2017年C++标准在9.4.2中提到case
标签时说:“常量表达式应是转换后的常量表达式……”,并在8.20中定义了转换后的常量表达式,包含核心常量表达式,整数常量表达式和更多内容的四页文本。
总之,C++标准更宽泛地规定了在翻译时需要语言实现评估的内容。
“常量表达式”一词用词不当。 更贴切的描述是,这些表达式是语言实现在翻译程序时需要能够解析为特定值的表达式。 C++标准比C标准需要更多的实现。
6.8.4.2开关语句P3:
每个大小写标签的表达式应为整数常量表达式
,且同一switch语句中的两个大小写常量表达式在转换后不得具有相同的值。
6.6常数表达式P6:
整数常量表达式应具有整数类型,且仅具有整数常量,枚举常量,字符常量,结果为整数常量的sizeof表达式以及作为强制转换的直接操作数的浮动常量的操作数。
这样定义它的原因是为了能够静态地计算代码中每个条件的偏移量。 否则,通过依次检查每个条件,与嵌套的一系列条件相比,它不会加快代码的速度。