Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 空宏何时不是0?_C_Null_Macros_History - Fatal编程技术网

C 空宏何时不是0?

C 空宏何时不是0?,c,null,macros,history,C,Null,Macros,History,我隐约记得几年前读过这篇文章,但我在网上找不到任何参考资料 你能给我一个空宏没有扩展到0的例子吗 为清晰起见进行编辑:现在它扩展为((void*)0),(0),或(0L)。然而,有些体系结构早就被遗忘了,因为这是不正确的,NULL扩展到了不同的地址。差不多 #ifdef UNIVAC #define NULL (0xffff) #endif 我在找这样一台机器的例子 更新以解决问题: 在当前标准的背景下,我不是想问这个问题,也不是想用我不正确的术语让人们不安。然而,我的假设被公认的答

我隐约记得几年前读过这篇文章,但我在网上找不到任何参考资料

你能给我一个空宏没有扩展到0的例子吗

为清晰起见进行编辑:现在它扩展为
((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历史》中从未有过一段时间,NULL//C>扩展到某些特定的不是<代码> 0 >代码>,除非你认为<代码>(空洞*)0 < /代码>为“不是0”。但是
(void*)0
for
NULL
至今仍被广泛使用。

在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*
字<代码>字符*