简体   繁体   English

(size_t)((char *)0)不会等于0吗?

[英]Does (size_t)((char *)0) ever not evaluate to 0?

According to the responses in "Why subtract null pointer in offsetof()?" 根据“为什么在offsetof()中减去空指针?”中的响应。 (and my reading of K&R), the C standard doesn't require that (size_t)((char *)0) == 0 . (以及我对K&R的阅读),C标准不需要(size_t)((char *)0) == 0 Still, I've never seen a situation where casting a null pointer to an integer type evaluates to anything else. 尽管如此,我从未见过将空指针强制转换为整数类型会影响其他任何情况的情况。

If there is a compiler or scenario where (size_t)((char *)0) != 0 , what is it? 如果存在(size_t)((char *)0) != 0的编译器或方案,那是什么?

Well, as you know, the physical representation of null pointer of a given type is not necessarily all-zero bit pattern. 众所周知,给定类型的空指针的物理表示不一定是全零位模式。 When you forcefully convert a pointer (any pointer) value to integer type, the result is implementation defined, but normally (and that's the intent) the numerical value of the pointer - the numerical address - remains unchanged, if possible. 当您将指针(任何指针)的值强制转换为整数类型时,结果是实现定义的,但是通常(这是目的)指针的数值(数字地址)尽可能保持不变。 This means that if on a given platform a null pointer of type char * is represented by 0xBAADF00D pattern (for example), the above expression will evaluate to 0xBAADF00D , and not to zero. 这意味着,如果在给定平台上用0xBAADF00D模式(例如)表示char *类型的空指针,则上述表达式的计算结果为0xBAADF00D ,而不是零。 Of course, for that you'd need a platform with non-zero null-pointers. 当然,为此,您将需要一个具有非零空指针的平台。 I personally never worked with such platforms, although I heard about a number of real platforms like that out there (like, in the realm of embedded platforms it is not something unusual). 我个人从来没有使用过这样的平台,尽管我听说过那里有很多类似的真实平台(例如,在嵌入式平台领域这并不稀奇)。

Moreover, as an additional note, null pointer values of different types can have different physical representations, meaning that in theory you can get different values from (size_t) ((int *) 0) , (size_t) ((char *) 0) and (size_t) ((double *) 0) . 此外,需要特别注意的是,不同类型的空指针值可以具有不同的物理表示形式,这意味着从理论上讲,您可以从(size_t) ((int *) 0)(size_t) ((char *) 0)获得不同的值。和(size_t) ((double *) 0) But that would be a rather exotic situation, albeit perfectly possible from the point of view of abstract C language. 但这将是一个相当奇特的情况,尽管从抽象C语言的角度来看这是完全可能的。

PS Read here (C FAQ) for some examples of actual platforms with non-zero null pointers. PS 在此处阅读(C FAQ),了解带有非零空指针的实际平台的一些示例。

The only thing that the C standard requires of a null pointer's runtime representation is (6.3.2.3/3 "Pointers"): C标准要求空指针的运行时表示的唯一内容是(6.3.2.3/3“ Pointers”):

...the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. ...得到的指针称为空指针,保证将不相等的指针与指向任何对象或函数的指针进行比较。 Conversion of a null pointer to another pointer type yields a null pointer of that type. 将空指针转换为另一种指针类型会产生该类型的空指针。

Any two null pointers shall compare equal. 任何两个空指针应比较相等。

Your question is an interesting one, though. 不过,您的问题很有趣。 Personally, I'm unaware of a platform that doesn't use the runtime value 0 to represent a null pointer. 就个人而言,我不知道没有使用运行时值0表示空指针的平台。 However, the standard doesn't require it, so if you can avoid the assumption in your code, why not? 但是,该标准不需要它,因此,如果可以避免代码中的假设,为什么不这样做呢?

I'd also be interested in anyone who knows of a system that uses a non-zero runtime value for a null pointer. 我也会对知道使用空指针的非零运行时值的系统的任何人感兴趣。

The C99 standard says that when you convert an integer value 0 to a pointer, it becomes a NULL pointer. C99标准说,当您将整数值0转换为指针时,它将变为NULL指针。 So ((char*)0) is a NULL pointer. 因此((char*)0)是NULL指针。 A NULL pointer need not have an actual binary representation of 0 . NULL指针不必具有实际的二进制表示形式0 It can be, for example 0x12345678 . 例如,它可以是0x12345678

The C standard further states that when you convert a NULL pointer to an integer constant, the result is "implementation-defined". C标准进一步指出,将NULL指针转换为整数常量时,结果是“实现定义的”。 In reality, what compilers do is simply cast the use the numerical value of the pointer to the corresponding integer value, as AndreyT said. 实际上,如AndreyT所说,编译器所做的只是将指针的数值转换为相应的整数值。 So in the example above, the integer value might end up being 0x12345678 , though technically it could be anything at all (ie. the compiler is allowed to say "converting a NULL pointer back to an integer value results in value 0xDEADBEEF "). 因此,在上面的示例中,整数值最终可能是0x12345678 ,尽管从技术上讲它可能是任何东西(即,允许编译器说“将NULL指针转换回整数值会导致值0xDEADBEEF ”)。 Note that this means that even on platforms where the NULL pointer has the value 0 , the compiler is allowed to convert it to an arbitrary integer value upon conversion. 请注意,这意味着即使在NULL指针的值为0 ,编译器也可以在转换时将其转换为任意整数值。 In reality, however, no compilers do that because it would be fairly insane. 但是,实际上,没有编译器会这样做,因为那样会很疯狂。

So, yes, the C standard allows a lot of things. 因此,是的,C标准允许很多事情。 In reality, any platform you are likely to work on will represent a NULL pointer as 0 and converting a NULL pointer to an integer value will result in 0 . 实际上,您可能使用的任何平台都将NULL指针表示为0而将NULL指针转换为整数值将得到0 Look here (section 1.14) for a list of some exceptions of (obscure) architectures which do not use 0 for a NULL pointer. 在这里(第1.14节)中列出了(晦涩的)体系结构的一些例外,这些例外不将0用作NULL指针。

This doesn't apply to char* or even C, but a smart pointer class which indexes into an array might choose to represent NULL as -1 because 0 is a valid array index. 这不适用于char*甚至C,但是对数组进行索引的智能指针类可能选择将NULL表示为-1因为0是有效的数组索引。

Considering the idiom of memset( my_new_struct, 0, sizeof my_new_struct ); 考虑memset( my_new_struct, 0, sizeof my_new_struct );的成语memset( my_new_struct, 0, sizeof my_new_struct ); , even a debugging-centric system is unlikely to break that identity. ,即使以调试为中心的系统也不太可能破坏该身份。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM