C 空宏何时不是0?
我隐约记得几年前读过这篇文章,但我在网上找不到任何参考资料 你能给我一个空宏没有扩展到0的例子吗 为清晰起见进行编辑:现在它扩展为C 空宏何时不是0?,c,null,macros,history,C,Null,Macros,History,我隐约记得几年前读过这篇文章,但我在网上找不到任何参考资料 你能给我一个空宏没有扩展到0的例子吗 为清晰起见进行编辑:现在它扩展为((void*)0),(0),或(0L)。然而,有些体系结构早就被遗忘了,因为这是不正确的,NULL扩展到了不同的地址。差不多 #ifdef UNIVAC #define NULL (0xffff) #endif 我在找这样一台机器的例子 更新以解决问题: 在当前标准的背景下,我不是想问这个问题,也不是想用我不正确的术语让人们不安。然而,我的假设被公认的答
((void*)0)
,(0)
,或(0L)
。然而,有些体系结构早就被遗忘了,因为这是不正确的,NULL扩展到了不同的地址。差不多
#ifdef UNIVAC
#define NULL (0xffff)
#endif
我在找这样一台机器的例子
更新以解决问题:
在当前标准的背景下,我不是想问这个问题,也不是想用我不正确的术语让人们不安。然而,我的假设被公认的答案所证实:
后来的模型使用了[blah],显然是为了迎合所有现存的编写不好的C代码,这些代码做出了错误的假设。
有关当前标准中空指针的讨论,请参见。在C编译器中,它可以扩展到“
((void*)0)
”(但不必这样做)。这对于C++编译器来说是不起作用的。
另请参见C FAQ,其中有一整章介绍。很久以前,当它被键入为
((void*)0)
或其他特定于机器的方式时,该机器没有使用全零位模式
一些平台(某些CDC或Honeywell机器)的NULL位模式不同(即,并非全零),尽管ISO/ANSI通过指定源代码中的0
是正确的NULL指针(无论底层位模式如何),修复了C90批准之前的问题。从C116.3.2.3指针/4
(尽管如前所述,该措辞可追溯至C90):
值为0
的整型常量表达式或转换为类型void*
的此类表达式称为空指针常量
C中的
NULL
宏扩展为实现定义的NULL指针常量。它可以是任何东西(因为它是实现定义的),但在指针上下文中,效果总是相同的,就像它扩展为常量0
《标准C历史》中从未有过一段时间,
(void*)0
forNULL
至今仍被广泛使用。在GNU libio.h文件中:
#ifndef NULL
# if defined __GNUG__ && \
(__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
# define NULL (__null)
# else
# if !defined(__cplusplus)
# define NULL ((void*)0)
# else
# define NULL (0)
# endif
# endif
#endif
注意uucplusplus上的条件编译。由于指针的规则更严格,C++不能使用((空洞*)0);标准要求NULL为0。C允许空值的其他定义。在现代C中,
void*pointer=0代码>用于初始化“指针”,使其不指向任何对象。具体到平台,是否通过将“指针”的位设置为全零来实现
在过去,指针上下文中“0”的这种形式含义尚未确定。有必要将指针设置为平台视为“不指向任何地方”的实际值。例如,平台可能会选择某个固定地址,而该地址永远不会将页面映射到该地址。在这种情况下,在旧编译器中,平台可能已将NULL
定义为:
#define NULL ((void*)0xFFFFF000)
当然,今天,没有理由不将其定义为((void*)0)
C FAQ中有一些非0空表示的历史机器示例
从,:
问:说真的,有没有实际的机器真的使用了非零null
指针,或指向不同对象的指针的不同表示形式
类型
答:Prime 50系列使用段07777,零位偏移量为0
指针,至少用于PL/I。以后的模型使用段0,偏移量0用于
C中的空指针,需要新的指令,如TCNP(Test
C空指针),显然是对所有现存的
写得很差的C代码,做出了错误的假设。更老的
字寻址的主机也因需要更大的容量而臭名昭著
字节指针(char*
)大于单词指针(int*
)
DataGeneral中的EclipseMV系列在架构上有三种
支持的指针格式(字、字节和位指针),其中两种
由C编译器使用:用于char*
和void*
的字节指针,以及word
其他一切的指针。由于历史原因,
32位MV线从16位Nova线的演变,word
指针和字节指针具有偏移量、间接寻址和环
字中不同位置的保护位。传递不匹配的
指向导致保护故障的函数的指针格式。
最后,mvc编译器添加了许多兼容性选项以供尝试
处理指针类型不匹配错误的代码
一些霍尼韦尔公牛大型机使用位模式06000来
(内部)空指针
CDC Cyber 180系列有48位指针,由一个环组成,
段和偏移。大多数用户(在环11中)都有
0xB00000000000。这在旧的CDC机器上很常见
使用所有一位字作为所有类型数据的特殊标志,
包括无效地址
旧的HP 3000系列对字节使用不同的寻址方案
地址比单词地址更重要;就像上面的几台机器一样
因此,它对char*
和void*
使用不同的表示形式
指针,而不是其他指针
Symbolics Lisp机器是一种标记的体系结构,它甚至没有
常规数字指针;它使用成对的
(基本上是
不存在作为C空指针的
句柄)
根据使用的“内存型号”,8086系列处理器(PC
兼容)可使用16位数据指针和32位函数
指针,反之亦然
一些64位Cray机器在a的较低48位表示int*
字<代码>字符*