尽管我已经超过了C11标准,但我无法看到左旋是否在_Generic表达式中作为控制表达式转换为右值时的问题的解决方案。例如,以下函数是返回1还是0?
int func()
{
const int x;
return _Generic( x, int: 1, default: 0 );
}
在标准中,左值转换定义如下(6.3.2.1.2):
除非它是sizeof运算符的操作数,_Alignof运算符,一元&运算符。运算符,++运算符, - 运算符或者左运算符。运算符或赋值运算符,没有数组类型的左值被转换为存储在指定对象中的值(并且不再是左值);这称为左值转换。如果左值具有限定类型,则该值具有左值类型的非限定版本;另外,如果左值具有原子类型,则该值具有左值类型的非原子版本;否则,该值具有左值的类型......
显然,func返回1.控制表达式' x'经历左值转换,因为它没有出现在例外情况之一中。因此,它的类型为 int ,并且选择了1。
另一方面,标准说(6.5.1.1.2):
...泛型关联中的类型名称应指定除可变修改类型之外的完整对象类型...
和(6.3.2.1.3):
除非它是sizeof运算符,_Alignof运算符或一元&运算符的操作数。运算符,或者是用于初始化数组的字符串文字,具有类型''数组类型''的表达式将转换为类型为''指向类型'的指针的表达式,指向数组对象的初始元素,不是左值......
明确排除我可以看到的可变修改类型的唯一原因是允许数组但不允许变量长度数组(因为类型已经要求是完整的对象类型)。由于似乎很清楚左值转换和指针转换既适用也不适用于_Generic控制表达式,这表明转换不会发生。否则,排除可变修改类型是多余的,非常混乱。
在我看来,这证明了左值转换隐式仅与求值语句相关的论证,并且不评估_Generic的控制表达式。根据这种理解,没有左值转换,并且在给出的示例中,x' x'有未转换的 const int 类型,因此func返回0。
标准中是否有任何内容可以澄清此问题?特别是,func在任何符合要求的实现上都具有相同的返回值吗?最后,流行的编译器(例如,clang,gcc等)在这个问题上是否一致?
我应该注意到我正在使用该标准的委员会草案,所以如果最终版本澄清了这一点,那么请告诉我。