在32位C编译器(GCC)中,sizeof(*NULL)为何等于1?
为什么32位GCC中
sizeof(*NULL)的结果是1? 这个问题挺有意思的,我来一步步给你掰扯清楚——你已经知道sizeof是编译期运算符而非函数,这是理解这个问题的核心基础,接下来我们拆解关键原因:
- 先明确32位GCC里NULL的定义:通常它会被预定义为
((void *)0),也就是一个void类型的空指针。少数场景下也可能被定义为整数常量0,但两种情况的最终结果一致。 - sizeof的核心特性:只推导类型,不求值表达式:这是最关键的一点!
*NULL这个表达式不会真的去访问内存地址0(那会直接触发段错误),sizeof只需要在编译阶段推导出这个表达式的类型,然后返回该类型的字节大小。 - 编译器对
*void*的特殊兼容处理:严格来说,C标准里直接解引用void*是不合法的,因为void是无类型的。但因为sizeof的操作数是未求值表达式,GCC在这里做了兼容处理:它会把*(void*)这种表达式的类型默认视为char类型。而根据C标准,char的大小永远是1,不管是32位还是64位编译环境。 - 如果NULL是整数0的情况:当NULL被定义为整数常量
0时,*0里的0会被当作空指针常量(C标准规定整数常量0可以隐式转换为任何指针类型),编译器同样会默认把这个解引用后的类型推导为char,所以sizeof的结果还是1。
另外要注意:这种行为其实是GCC的特定处理,严格来说*NULL属于C标准里的未定义行为,但因为sizeof不求值,所以编译器不会报错,反而给出了一个符合直觉的结果。如果是在C环境里,这种写法会直接编译失败,因为C对类型的检查更严格。
内容的提问来源于stack exchange,提问作者Utkarsh Agarwal
相关产品推荐
相关产品推荐

