问题描述
This答案正确地解释了有关空指针的问题。在空指针下的最后一段说
如果基础体系结构的空指针值定义为地址0xDEADBEEF,则由编译器来解决此问题。
现在,如果某些体系结构内部将Null指针值定义为非零。这些if语句如何有效。编译器如何解决它们?
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
毕竟,将空指针常量分配给指针后,您会得到一个空指针,并且空指针常量始终是0
或(void *)0
。进一步的this答案说
我真的无法理解这个字面量0
在初始化为指针时如何变成非全零。这不是一个简单的初始化吗?此外,如果我的空指针值不为零,那么上述3个if语句如何检查空指针?这不是我们将非零null指针值与0
文字值进行比较吗?
解决方法
if (!pointer)
如果C实现将值DEADBEEF 16 用作空指针,则编译器会将if (!pointer)
编译为以下代码:
compare pointer,#0xDEADBEEF
branch-if-not-equal else-clause
if (pointer == 0)
一个整数常量零等于“空指针常量”(C 2018 6.3.2.3 3)。将指针与空指针常量进行比较时,会将空指针常量转换为指针的类型(6.5.9 5)。编译器将通过为所得指针生成DEADBEEF 16 来实现此转换。然后它将pointer
与DEADBEEF 16 进行比较并相应地分支。
简而言之,仅仅是因为源代码中出现了字符“ 0”,并不意味着编译器必须在生成的指令中使用零。它会生成完成工作所需的任何指令和值。
我真的不明白当初始化为指针时,这个文字
0
怎么变成非全零。
关于字符“ 0”的任何事情都没有迫使编译器为其赋予零值。 “ 0”的代码在ASCII中为48,在EBCDIC中为240,因此,当编译器处理此字符或其他字符时,编译器并非从零开始。通常,在处理数字时,它必须读取数字并做一些算术运算以计算数字表示的数字。是导致“ 0”代表值零或导致“ 23”代表值二十三的软件。为了使“ 0”代表空指针,只要在上下文中将“ 0”用作指针,编译器中的软件就会简单地替换空指针的内部值。
例如,在void *x = 0;
中,编译器可能最初将“ 0”转换为零,但这将成为数据结构的一部分,该数据结构还表示这是当前值为零的令牌或整数常量表达式。当编译器看到此整数常量表达式用于初始化指针时,它将更改该值,并将生成将指针初始化为空指针的内部值的代码。