C11及C2x标准中,条件运算符的第二、第三操作数能否为不完全对象类型?
关于C11/C2x标准中条件运算符操作数是否允许不完全对象类型的疑问
问题
依据C11及C2x标准,我认为条件运算符的第二、第三操作数可以是不完全对象类型,这个理解是否正确?
测试代码
struct x y; void f(void) { 1 ? y : y; }
各编译器编译结果
Clang(-std=c11 -pedantic -Wall -Wextra)
$ clang t0.c -std=c11 -pedantic -Wall -Wextra t0.c:2:24: warning: expression result unused [-Wunused-value]
GCC(-std=c11 -pedantic -Wall -Wextra)
$ gcc t0.c -std=c11 -pedantic -Wall -Wextra t0.c: In function 'f': t0.c:2:20: error: 'y' has an incomplete type 'struct x' 2 | void f(void) { 1 ? y : y; } | ^ t0.c:2:24: error: 'y' has an incomplete type 'struct x' 2 | void f(void) { 1 ? y : y; }
MSVC(/std:c11)
$ cl t0.c /std:c11 t0.c(1): error C2079: 'y' uses undefined struct 'x'
ICC(-std=c11 -pedantic -Wall -Wextra)
$ icc t0.c -std=c11 -pedantic -Wall -Wextra t0.c(2): error: incomplete type is not allowed void f(void) { 1 ? y : y; } ^ t0.c(2): error: incomplete type is not allowed void f(void) { 1 ? y : y; } ^
结论:你的理解不正确
按照C11标准(C2x在这部分规则上没有显著变化),不完全类型的左值不能作为条件运算符的操作数,具体依据如下:
C11标准6.3.2.1节《左值、数组和函数指示符》第2款明确规定:只有当不完全类型的左值作为sizeof运算符、_Alignof运算符、一元&运算符、++运算符、--运算符或赋值运算符的左操作数时,才能出现在表达式中;其余场景下,具有不完全类型的左值不得用于表达式。
条件运算符的第二、第三操作数属于普通表达式范畴,不在上述允许的例外场景内,因此不能使用不完全对象类型的操作数。
编译器的表现也验证了这一点:GCC、MSVC、ICC均直接报错,符合标准要求;仅Clang给出未使用值的警告,这属于编译器的宽松实现,不能作为符合标准的依据。
内容的提问来源于stack exchange,提问作者pmor
相关产品推荐
相关产品推荐

