有时,有人读到旧的 C 编译器有NULL
not0
或(void *)0
. 我对 C 标准的理解是,即使平台的空指针位模式不为零,转换为指针的整数 0(隐式或显式)仍然是空指针,并在内部存储为平台的空指针位图案。
但是例如,这里是这样写的:
在一些较旧的 C 编译器中,
NULL
对一些奇怪的东西进行了各种定义,因此您必须更加小心。
我记得不时在其他地方读到这个。除非这是一个持久的都市传说,否则还有哪些其他定义NULL
在使用?
有时,有人读到旧的 C 编译器有NULL
not0
或(void *)0
. 我对 C 标准的理解是,即使平台的空指针位模式不为零,转换为指针的整数 0(隐式或显式)仍然是空指针,并在内部存储为平台的空指针位图案。
但是例如,这里是这样写的:
在一些较旧的 C 编译器中,
NULL
对一些奇怪的东西进行了各种定义,因此您必须更加小心。
我记得不时在其他地方读到这个。除非这是一个持久的都市传说,否则还有哪些其他定义NULL
在使用?
当您说空指针常量(常量整数零或常量整数零强制转换为void *
)保证被正确转换为目标类型的空指针的适当内部表示时,您是绝对正确的。这意味着不需要任何其他定义NULL
. 0
或(void *) 0
将在任何地方工作。
然而同时,C 语言的早期版本并没有做出这样的保证,也没有标准的NULL
宏。将整数值分配给指针变量会导致指针从字面上指向由该整数值表示的地址。将常量分配0
给指针只是使其指向地址0
。如果用户想在他们的程序中保留一个指针值,他们必须手动选择一个“一次性”地址来用于该目的。
在语言标准化之前和前面提到的零到指针转换规则出现之前,宏很有可能NULL
进入非正式使用。那时NULL
必须将其定义为表示该确切保留地址的整数值。0xBAADFOOD
例如,想要将地址用于空指针的预标准 C 实现将定义NULL
为0xBAADFOOD
. 不过,我无法确认这一点,因为我不知道宏何时NULL
首次出现在“野外”。
你完全正确。
您可能会遇到的“奇怪的事情”之一是 #define'ing NULL to ((void *)0)
,这将导致将 NULL 用作除指针之外的任何东西的代码失败。
以下是其他一些变体:
http://www.tutorialspoint.com/c_standard_library/c_macro_null.htm
#define NULL ((char *)0)
或者
#define NULL 0L
或者
#define NULL 0
还值得注意的是,C++ 11 引入nullptr
以提供 NULL、0 等的类型安全消歧。请参阅Much Ado about Nothing或 ( http://www.open-std.org/jtc1/sc22/wg21/docs /papers/2004/n1601.pdf </p>