对变长数组使用sizeof是否存在优势?相关技术疑问
关于变长数组(VLA)与sizeof表达式的疑问解答
问题背景
我维护的一段遗留代码中存在类似以下的写法,用GCC的-Wvla编译选项会触发警告:
typedef struct entry { unsigned index; unsigned reserved; unsigned value; } entry_t; int main(int argc, char **argv) { long pa = 0; long res = pa + sizeof(entry_t[10 - argc]); return res; }
编译警告输出:
$ gcc -g -Wvla repro-vla.c repro-vla.c: In function ‘main’: repro-vla.c:9:5: warning: ISO C90 forbids variable length array [-Wvla] 9 | long res = pa + sizeof(entry_t[10 - argc]); | ^~~~
针对sizeof(entry_t[10 - argc])这个表达式,有两个疑问:
1. 对这段代码的理解是否正确?
你的理解有偏差:这个表达式并不会创建临时匿名数组。sizeof是运算符,作用于类型或表达式时,只会计算对应类型的大小,不会实际分配内存。这里entry_t[10 - argc]是一个变长数组(VLA)类型——因为数组的大小由运行时变量argc决定,GCC触发-Wvla警告,正是因为代码中使用了变长数组类型,哪怕只是在sizeof运算符内部。
2. 该表达式与sizeof(entry_t) * (10-argc)有何区别?
从数值计算结果来看,两者在10 - argc为正数时是等价的,但本质有两点核心区别:
- 语法标准兼容性:
sizeof(entry_t[10 - argc])依赖C99引入的变长数组特性,而C90标准不支持VLA,因此会触发-Wvla警告;sizeof(entry_t) * (10-argc)是普通的算术运算,不涉及VLA类型,兼容C90及更高版本标准,不会触发警告。 - 代码可读性:后者直接表达“单个元素大小乘以元素个数”的逻辑,比前者更直观,维护成本更低。
另外你提到的argc>=10时的下溢问题,两种写法都未处理:如果10 - argc为负数,前者中VLA的大小为负数属于未定义行为,后者会得到负数的计算结果,同样不符合预期,需要额外的边界检查来规避。
内容的提问来源于stack exchange,提问作者Grigory Rechistov
相关产品推荐
相关产品推荐

