是否可以安全地假设NULL常数为零? [英] Is it safe to assume that the NULL constant is zero?

查看:136
本文介绍了是否可以安全地假设NULL常数为零?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Richard Reese写的《 理解和使用C指针》 说:

The book Understanding and Using C Pointers, by Richard Reese says:

null概念是null指针支持的抽象 持续的.该常数可以是或可以不是常数零. A C 程序员不必关心他们的实际内部 表示形式.

The null concept is an abstraction supported by the null pointer constant. This constant may or may not be a constant zero. A C programmer need not be concerned with their actual internal representation.

我的问题是,由于此常数可能为零,也可能不是常数零",因此在我的代码中执行以下操作是否安全:

My question is, since "this constant may or may not be a constant zero," is it safe for me to do things like the below in my code:

int *ptr = NULL;
// Some code which probably sets ptr to a valid memory address

if(!ptr)
{
   ERROR();
}

如果NULL不为0,则if子句的值可能为true.

If NULL is not 0, there is a chance that the if clause will evaluate to true.

推荐答案

可以安全地假设NULL常量为零吗?

Is it safe to assume that the NULL constant is zero?

NULL将比较等于0.
NULL非常,通常是零位模式. NULL可能是非零的位模式-但最近没有出现.

NULL will compare equal to 0.
NULL is very commonly a zero bit pattern. It is possible for NULL to be a non-zero bit pattern - but not seen these days.

OP至少混合了4种东西:NULL空指针常量空指针,并将空指针与0进行比较. C没有定义 NULL常量.

OP is mixing as least 4 things: NULL, null pointer constant, null pointer, comparing a null pointer to 0. C does not define a NULL constant.

NULL

NULL

NULL是一个宏",它扩展为实现定义的null 指针常量" C17dr§7.19 3

NULL is a macro "which expands to an implementation-defined null pointer constant" C17dr § 7.19 3

空指针常量

null pointer constant

值为0的整数常量表达式或此类表达式 强制转换为类型void *,称为空指针常量. C17dr§§ 6.3.2.3 3

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. C17dr § § 6.3.2.3 3

因此 null指针常量类型可以是intunsignedlong,...或void *.

Thus the type of a null pointer constant may be int, unsigned, long, ... or void * .

当整数 1 时,空指针常量 value 为0.像((void *)0)这样的指针,其值/编码为未标明.它的确确实具有零的位模式,但并未指定.

When an integer1, the null pointer constant value is 0. As a pointer like ((void *)0), its value/encoding is not specified. It ubiquitously does have the bit pattern of zeros, but is not specified so.

可能有许多空指针常量.它们彼此相等.

There may be many null pointer constants. They all compare equal to each other.

注意:当 null指针常量 size 为整数时,它可能与对象指针的大小不同.通常可以通过根据需要添加L或两个后缀来避免这种大小差异.

Note: the size of a null pointer constant, when it is an integer, may differ from the size of an object pointer. This size difference is often avoided by appending a L or two suffix as needed.

空指针

null pointer

如果将空指针常量转换为指针类型,则 得到的指针称为 null指针,可以保证进行比较 不等于指向任何对象或函数的指针. C17dr§6.3.2.3 3

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. C17dr § § 6.3.2.3 3

将空指针转换为另一种指针类型会产生一个空值 该类型的指针.任何两个空指针应比较相等. C17dr §6.3.2.3 4

Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal. C17dr § § 6.3.2.3 4

空指针的类型是某种指针,可以是int *, char *之类的对象指针,也可以是int (*)(int, int)void *之类的函数指针.

The type of null pointer is some pointer, either an object pointer like int *, char * or function pointer like int (*)(int, int) or void *.

未指定空指针 value .它的确确实具有零的位模式,但并未指定.

The value of a null pointer is not specified. It ubiquitously does have the bit pattern of zeros, but is not specified so.

所有 null指针均比较相等,无论其编码如何.

All null pointer compare as equal, regardless of their encoding.

比较空指针为0

comparing a null pointer to 0

if(!ptr)if(!(ptr != 0))相同.将空指针指针ptr与0进行比较时,零将转换为指针,即相同类型的空指针:.这两个 null指针(可能具有不同的位模式)比较相等.

if(!ptr) is the same as if(!(ptr != 0)). When the pointer ptr, which is a null pointer, is compared to 0, the zero is converted to a pointer, a null pointer of the same type: int *. These 2 null pointers, which could have different bit patterns, compare as equal.

那么当不安全地假设NULL常数为零时?

NULL可能是((void*)0),并且其位模式可能与零不同.不管其编码如何,它的确比上面等于0.讨论了调用指针比较,而不是整数比较.即使((void*)0)都是零位,将NULL转换为整数也可能不会导致整数值0.

NULL may be a ((void*)0) and its bit pattern may differ from zeros. It does compare equal to 0 as above regardless of its encoding. Recall pointer compares have been discussed, not integer compares. Converting NULL to an integer may not result in an integer value of 0 even if ((void*)0) was all zero bits.

printf("%ju\n", (uintmax_t)(uintptr_t)NULL); // Possible not 0

请注意,这是将指针转换为整数,而不是if(!ptr)的情况,其中将0转换为指针.

Notice this is converting a pointer to an integer, not the case of if(!ptr) where a 0 was converted to a pointer.

C规范包含许多旧的做事方式,并且对新颖的新方式开放.我从未遇到过NULL不是全零位模式的实现.假设存在许多假定NULL全部为零位的代码,我怀疑只有旧的晦涩的实现曾经使用过非零位模式NULL,并且NULL几乎可以肯定是全零位模式.

The C spec embraces many old ways of doing things and is open to novel new ones. I have never came across an implementation where NULL was not an all zeros bit pattern. Given much code exist that assumes NULL is all zero bits, I suspect only old obscure implementations ever used a non-zero bit-pattern NULL and that NULL can be all but certain to be an all zero bit pattern.

1 空指针常量是1)整数或2)void*. 当整数...时"是指第一种情况,而不是第二种情况的转换或转换,如(int)((void*)0)所示.

1 The null pointer constant is 1) an integer or 2) a void*. "When an integer ..." refers to the first case, not a cast or conversion of the second case as in (int)((void*)0).

这篇关于是否可以安全地假设NULL常数为零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆