You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对变长数组使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:53:26