sizeof(type_name)中type_name的求值条件及GCC特殊行为问询
C语言
sizeof运算符类型名参数的求值疑问 背景
C17标准(6.5.3.4 ¶2)规定:
sizeof运算符返回操作数的字节大小,操作数可以是表达式或带括号的类型名。大小由操作数的类型决定,结果为整数。若操作数是变长数组(VLA)类型,则对操作数求值;否则不对操作数求值,结果为整数常量。
该表述未区分sizeof的两种语法场景:
sizeof一元表达式sizeof(类型名)
笔者认为类型名并非“拥有”类型,而是“指代”类型。若以类型名为参数,直观上应表述为对其中所有赋值表达式求值(无论准确性,只为清晰)。
综上,笔者理解为:在sizeof(type)中,type内部的所有表达式当且仅当type是VLA类型时才会被求值。
问题
基于上述理解,以下代码的最后一条printf语句结果令人意外:
#include <stdio.h> void f(int i) { printf("side effect %d; ", i); } int main(void) { int n = 9; int a[n]; printf("%zu\n", sizeof a); // 36 printf("%zu\n", sizeof a[n++]); // 4 printf("%d\n", n); // 9 printf("%zu\n", sizeof(int [n++])); // 36 printf("%d\n", n); // 10 printf("%zu\n", sizeof(int [(f(0), 100)])); // side effect 0; 400 (操作数类型:int,非VLA类型) return 0; }
(f的参数int i用于调试和区分不同函数调用。)
- 简而言之:
int [(f(0), 100)]指代类型int [100],这不是VLA类型。那么:为什么f(0)会被求值? - 更普遍的问题是:
sizeof(type_name)中type_name(或其内部表达式)被求值的准确条件是什么?
顺带一提,sizeof(int [f(0), 100])(数组大小的逗号表达式未加括号)会报错,相关讨论此处不展开。
其他参考
- C17草案中关于数组声明符语法的相关内容见:6.7.7 ¶1、6.7.6.2 ¶3。
- Keith Thompson关于VLA的回答具有参考价值,但本文问题并非针对VLA本身(仅用于对比)。
内容的提问来源于stack exchange,提问作者Lover of Structure
相关产品推荐
相关产品推荐

