在32位C编译器上sizeof(* NULL)如何等于1?

时间:2018-03-28 18:14:24

标签: c pointers gcc

我最近了解到sizeof不是函数,实际上是在编译时进行评估。

但我仍然无法弄清楚sizeof(*NULL)如何等于1。

编辑:我特地在这里谈论gcc。

4 个答案:

答案 0 :(得分:10)

这取决于编译器和标准库。使用GCC和glibc,NULL定义为(void*)0,GCC具有an extension,允许使用voidsizeof(void) == 1指针进行指针算术。如果没有此扩展,编译器将产生错误。

标准库也可以将NULL定义为0。在这种情况下,sizeof(*NULL)也是非法的。

答案 1 :(得分:3)

标准不保证sizeof(*NULL)返回的值,这足以在实践中不使用此构造。

您的代码使用实现定义的行为。

  

7.173宏是

NULL
     

扩展为实现定义的空指针常量

这意味着该标准不保证您的代码将要编译,更不用说产生某个值了。

在将宏NULL定义为((void*)0)的系统上,您的代码将触发一个应被视为错误的警告:

  

prog.c:4:28:错误:'sizeof'无效应用于void类型[-Werror = pointer-arith]

Demo.

答案 2 :(得分:2)

由于NULL的类型为void *,这意味着*NULL的类型为void。 C标准不允许使用void的大小,尽管有些编译器会作为扩展。

GCC中,它将void的大小视为1,以允许void *上的指针算术。

答案 3 :(得分:1)

在“旧时间”NULL被定义为:

#define NULL ((char *)0)

所以使用*NULL你得到一个大小为1的字符。(你仍然可以看到这样的定义隐藏在标题中,作为后退的情况,现在,从C90开始,char是替换为void)。

我不认为它是一个有效的代码(间接为NULL,也只是为了取大小)。

在某些编译器上,null为0l或仅0,这会在您的情况下出错。