如何编写C / C ++ code正常工作时的空指针是不是所有的零位 [英] How to write C/C++ code correctly when null pointer is not all bits zero
问题描述
由于 comp.lang.c常见问题解答说,有架构,其中空指针是不是所有的位零。所以,问题是什么是真正检查以下结构:
As the comp.lang.c FAQ says, there are architectures where the null pointer is not all bits zero. So the question is what actually checks the following construction:
void* p = get_some_pointer();
if (!p)
return;
我是不是比较 P
与机器相关的空指针还是我比较 P
与算术0?
Am I comparing p
with machine dependent null pointer or I'm comparing p
with arithmetic zero?
我应该写
void* p = get_some_pointer();
if (NULL == p)
return;
而不是要准备好这样的架构,或只是我的偏执?
instead to be ready for such architectures or is it just my paranoia?
推荐答案
根据C规格:
这是整型常量前pression值为0,或者这样的前pression
转换为类型为void *,被称为空指针常量。 55)如果一个空
指针常数转换为指针类型,将所得
指针,叫做空指针,是保证比较不等于一
指向任何对象或函数。
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. 55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
所以 0
是一个空指针常数。如果我们把它转换为指针类型,我们会得到一个空指针可能对某些架构非所有位为零。接下来让我们看看规格说,关于比较指针和空指针常量:
So 0
is a null pointer constant. And if we convert it to a pointer type we will get a null pointer that might be non-all-bits-zero for some architectures. Next let's see what the spec says about comparing pointers and a null pointer constant:
如果一个操作数是
指针,而另一个是一个空指针常数,空指针
常数转换为指针的类型。
If one operand is a pointer and the other is a null pointer constant, the null pointer constant is converted to the type of the pointer.
让我们考虑(P == 0)
:第一个 0
转换为空指针,然后 p
与空指针常量,其实际的比特值是体系结构相关的比较。
Let's consider (p == 0)
: first 0
is converted to a null pointer, and then p
is compared with a null pointer constant whose actual bit values are architecture-dependent.
接下来,看看有什么规范说的有关否定运算符:
Next, see what the spec says about the negation operator:
逻辑否定运算符的结果!为0,如果值的
操作比较不等于0,1,如果它的操作数的值进行比较
等于0的结果具有int类型。这位前pression!E是相当于
到(0 == E)。
The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).
这意味着(!P)
等同于(P == 0)
是,根据规范,测试 p
对机器定义的空指针常量。
This means that (!p)
is equivalent to (p == 0)
which is, according to the spec, testing p
against the machine-defined null pointer constant.
因此,你可以安全地写如果(!P)
甚至在架构,其中空指针常量是不是所有位归零。
Thus, you may safely write if (!p)
even on architectures where the null pointer constant is not all-bits-zero.
至于C ++中,空指针常量的定义是:
As for C++, a null pointer constant is defined as:
一个空指针常量是一个整型常量前pression(5.19)
整型prvalue计算结果为零或类型的prvalue
的std :: nullptr_t。空指针常量可以转换为指针
类型;其结果是该类型的空指针值,并
从对象指针或函数的所有其他价值区分
指针类型。
A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type.
这是接近我们有C,加上 nullptr
语法糖。运营商的行为 ==
被定义为:
Which is close to what we have for C, plus the nullptr
syntax sugar. The behavior of operator ==
is defined by:
此外,成员指针可以进行比较,或指向
成员和空指针常量。成员指针转换
(4.11)和资格转换(4.4)执行给他们带来
到一个常见的类型。如果一个操作数是一个空指针常数时,
常见的类型是其他操作数的类型。否则,该共同
类型是一个指针,成员类型相似(4.4),以一个类型
操作数,用CV-资格签名(4.4),这是
操作数类型的CV-资质签名的结合。 [ 注意:
这意味着任何成员指针可以比作一个空
指针常量。 - 注完]
In addition, pointers to members can be compared, or a pointer to member and a null pointer constant. Pointer to member conversions (4.11) and qualification conversions (4.4) are performed to bring them to a common type. If one operand is a null pointer constant, the common type is the type of the other operand. Otherwise, the common type is a pointer to member type similar (4.4) to the type of one of the operands, with a cv-qualification signature (4.4) that is the union of the cv-qualification signatures of the operand types. [ Note: this implies that any pointer to member can be compared to a null pointer constant. — end note ]
这导致了 0
转换为指针类型(为C)。对于否定运算符:
That leads to conversion of 0
to a pointer type (as for C). For the negation operator:
逻辑否定运算符的操作!在内容上
转换为布尔(第4章);如果转换后的值是真
操作数为真,否则为false。该结果的类型是布尔。
The operand of the logical negation operator ! is contextually converted to bool (Clause 4); its value is true if the converted operand is true and false otherwise. The type of the result is bool.
这意味着这个结果!P
依赖于从指针布尔
转换是如何进行的。标准说:
That means that result of !p
depends on how conversion from pointer to bool
is performed. The standard says:
有一个零值,空指针值或空成员指针值
转换为false;
A zero value, null pointer value, or null member pointer value is converted to false;
所以如果(P == NULL)
和如果(!P)
确实在C同样的事情++太
So if (p==NULL)
and if (!p)
does the same things in C++ too.
这篇关于如何编写C / C ++ code正常工作时的空指针是不是所有的零位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!