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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:57:47