为何x86-64 GCC 12.2中负大小数组的sizeof不触发错误?
负大小数组的sizeof操作未触发错误的原因
首先看你提供的代码:
#include <stdio.h> #define STATIC_ASSERT(x) ((void)sizeof(char[1 - 2*!(x)])) int main(void) { STATIC_ASSERT("State"[0] == 'j'); sizeof(char[-"State"[0]]); printf("%c, %d, %d", "State"[0], 1 - 2*!("State"[0] == 'j'), -"State"[0]); return 0; }
未触发数组大小为负的错误,核心原因有两点:
GCC默认编译选项的宽松检查
C标准规定,非变长数组(VLA)的大小必须是大于0的整数常量表达式,负大小属于约束违反,编译器应当诊断。但GCC在默认编译模式下(未开启严格标准检查),会跳过对sizeof内部数组大小的正负校验——因为sizeof仅计算类型大小,不会实际创建数组对象,GCC将其视为一种扩展行为,不强制报错。
如果你开启-pedantic、-std=c11这类严格标准选项,GCC就会抛出类似"ISO C forbids negative-size array"的警告或错误。sizeof操作符的特性
sizeof的操作数不会被求值,不管表达式里的数组大小是正还是负,都不会触发运行时的数组分配错误。对于代码里的char[-"State"[0]],"State"[0]是字符'S'(ASCII值83),因此-"State"[0]的值是-83,sizeof会直接计算该数组类型的大小:将-83转换为无符号的size_t类型(结果是一个极大的正整数),不会因为负大小触发错误。
内容的提问来源于stack exchange,提问作者user1806687
相关产品推荐
相关产品推荐

