NULL 宏什么时候不是 0? [英] When was the NULL macro not 0?
问题描述
我隐约记得几年前读过这本书,但我在网上找不到任何参考资料.
I vaguely remember reading about this a couple of years ago, but I can't find any reference on the net.
你能举个例子说明 NULL 宏没有扩展到 0 吗?
Can you give me an example where the NULL macro didn't expand to 0?
为清楚起见进行今天它扩展为 ((void *)0)
、(0)
或 (0L)
.然而,有些架构早已被遗忘,但事实并非如此,NULL 扩展到不同的地址.类似的东西
Edit for clarity: Today it expands to either ((void *)0)
, (0)
, or (0L)
. However, there were architectures long forgotten where this wasn't true, and NULL expanded to a different address. Something like
#ifdef UNIVAC
#define NULL (0xffff)
#endif
我正在寻找这种机器的示例.
I'm looking for an example of such a machine.
更新以解决问题:
我的意思不是在当前标准的背景下提出这个问题,或者用我不正确的术语让人们感到不安.但是,我的假设得到了接受的答案的证实:
I didn't mean this question in the context of current standards, or to upset people with my incorrect terminology. However, my assumptions were confirmed by the accepted answer:
后来的模型使用 [blah],显然是对所有现存的写得很糟糕的 C 代码做出错误假设的一种安慰.
Later models used [blah], evidently as a sop to all the extant poorly-written C code which made incorrect assumptions.
有关当前标准中空指针的讨论,请参阅 这个问题.
For a discussion about null pointers in the current standard, see this question.
推荐答案
C FAQ 中有一些历史机器具有非 0 NULL 表示的示例.
The C FAQ has some examples of historical machines with non-0 NULL representations.
问:说真的,有任何实际机器真正使用过非零 null指针,或指向不同的指针的不同表示类型?
Q: Seriously, have any actual machines really used nonzero null pointers, or different representations for pointers to different types?
A:Prime 50 系列使用了 07777 段,偏移量 0 表示 null指针,至少对于 PL/I.后来的模型使用段 0,偏移量 0 为C 中的空指针,需要新指令,例如 TCNP(测试C Null Pointer),显然是对 [footnote] 所有现存的写得不好的 C 代码做出了错误的假设.年纪大了,字寻址的 Prime 机器也因需要更大的机器而臭名昭著字节指针(char *
's)比字指针(int *
's).
A: The Prime 50 series used segment 07777, offset 0 for the null
pointer, at least for PL/I. Later models used segment 0, offset 0 for
null pointers in C, necessitating new instructions such as TCNP (Test
C Null Pointer), evidently as a sop to [footnote] all the extant
poorly-written C code which made incorrect assumptions. Older,
word-addressed Prime machines were also notorious for requiring larger
byte pointers (char *
's) than word pointers (int *
's).
Data General 的 Eclipse MV 系列在架构上具有三个支持的指针格式(字、字节和位指针),其中两种由 C 编译器使用:char *
和 void *
的字节指针,以及 word其他一切的指针.期间由于历史原因32 位 MV 线从 16 位 Nova 线演变而来,字指针和字节指针有偏移、间接和环字中不同位置的保护位.传递一个不匹配的指向函数的指针格式导致保护故障.最终,MV C 编译器添加了许多兼容性选项来尝试处理存在指针类型不匹配错误的代码.
The Eclipse MV series from Data General has three architecturally
supported pointer formats (word, byte, and bit pointers), two of which
are used by C compilers: byte pointers for char *
and void *
, and word
pointers for everything else. For historical reasons during the
evolution of the 32-bit MV line from the 16-bit Nova line, word
pointers and byte pointers had the offset, indirection, and ring
protection bits in different places in the word. Passing a mismatched
pointer format to a function resulted in protection faults.
Eventually, the MV C compiler added many compatibility options to try
to deal with code that had pointer type mismatch errors.
一些 Honeywell-Bull 大型机将位模式 06000 用于(内部)空指针.
Some Honeywell-Bull mainframes use the bit pattern 06000 for (internal) null pointers.
CDC Cyber 180 系列有 48 位指针,由一个环组成,段和偏移量.大多数用户(在第 11 环中)的空指针为0xB00000000000.在旧的 CDC 补码机器上很常见使用全一位字作为各种数据的特殊标志,包括无效地址.
The CDC Cyber 180 Series has 48-bit pointers consisting of a ring, segment, and offset. Most users (in ring 11) have null pointers of 0xB00000000000. It was common on old CDC ones-complement machines to use an all-one-bits word as a special flag for all kinds of data, including invalid addresses.
旧的 HP 3000 系列对字节使用不同的寻址方案地址比字地址;像上面的几台机器因此它对 char *
和 void *
使用不同的表示指针比其他指针.
The old HP 3000 series uses a different addressing scheme for byte
addresses than for word addresses; like several of the machines above
it therefore uses different representations for char *
and void *
pointers than for other pointers.
符号化的 Lisp 机器,一个标记的架构,甚至没有常规数字指针;它使用对 <NIL, 0>
(基本上是不存在的 句柄)作为 C 空指针.
The Symbolics Lisp Machine, a tagged architecture, does not even have
conventional numeric pointers; it uses the pair <NIL, 0>
(basically a
nonexistent <object, offset>
handle) as a C null pointer.
根据使用的内存模型",8086 系列处理器(PC兼容)可以使用 16 位数据指针和 32 位函数指针,反之亦然.
Depending on the "memory model" in use, 8086-family processors (PC compatibles) may use 16-bit data pointers and 32-bit function pointers, or vice versa.
一些 64 位 Cray 机器将 int *
表示为 a 的低 48 位单词;char *
还使用一些高 16 位来表示一个字内的字节地址.
Some 64-bit Cray machines represent int *
in the lower 48 bits of a
word; char *
additionally uses some of the upper 16 bits to indicate a
byte address within a word.
这篇关于NULL 宏什么时候不是 0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!