gpt4 book ai didi

c++ - 表达式 "(ptr == 0) != (ptr == (void*)0)"真的可以吗?

转载 作者:IT老高 更新时间:2023-10-28 12:44:55 25 4
gpt4 key购买 nike

我在 a forum thread 中阅读了此声明链接到 in a comment by @jsantander :

Keep in mind that when you assign or compare a pointer to zero, there is some special magic that occurs behind the scenes to use the correct pattern for the given pointer (which may not actually be zero). This is one of the reasons why things like #define NULL (void*)0 are evil – if you compare a char* to NULL that magic has been explicitly (and probably unknowingly) turned off, and an invalid result may happen. Just to be extra clear:

(my_char_ptr == 0) != (my_char_ptr == (void*)0)

所以按照我的理解,对于 NULL 指针为 0xffff 的架构,代码 if (ptr) 会将 ptr 与 0xffff 而不是 0。

这是真的吗?它是由 C++ 标准描述的吗?

如果为真,则意味着即使对于具有非零 NULL 指针值的架构,也可以安全地使用 0。

编辑

作为额外的说明,请考虑以下代码:

char *ptr;
memset(&ptr, 0, sizeof(ptr));
if ((ptr == (void*)0) && (ptr != 0)) {
printf("It can happen.\n");
}

这就是我理解此论坛帖子声明的方式。

最佳答案

您的问题分为两部分。我将从:

If true, it would mean that 0 can be safely used even for architectures that have a non-zero NULL pointer value.

你混淆了“值(value)”和“表现”。空指针的称为空指针值representation 是内存中用于存储此值的位。空指针的表示可以是任何东西,并不要求它是全位为零的。

在代码中:

char *p = 0;

p保证为空指针。它可能没有全为零。

这并不比代码更“神奇”:

float f = 5;

f没有与 int 5 相同的表示形式(内存中的位模式)可以,但没有问题。

C++ 标准对此进行了定义。文本在 C++11 中有所改变,增加了 nullptr。 ;但是在所有版本的 C 和 C++ 中,整数文字 0当转换为指针类型时会生成一个空指针。

来自 C++11:

A null pointer constant is an integral constant expression 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. Such a conversion is called a null pointer conversion.

0是一个空指针常量,并且(char *)0例如是 char * 类型的 空指针值 .

空指针是否全为零无关紧要。重要的是,当您转换值为 0 的整数 constexpr 时,保证会生成一个空指针。指向指针类型。

转到问题的另一部分。 你引用的文字完全是垃圾。正如我在上面讨论的那样,类型之间的转换会导致不同的表示形式这一想法没有“魔法”。

代码 my_char_ptr == NULL保证测试是否my_char_ptr是一个空指针。

如果你用自己的源代码编写,那将是邪恶的,#define NULL (void*)0 .这是因为定义任何可能由标准头文件定义的宏都是未定义的行为。

但是,标准 header 可以编写任何他们喜欢的内容,以便满足空指针的标准要求。编译器可以在标准头代码中“变魔术”;例如,不必有一个名为 iostream 的文件。在文件系统上;编译器可以看到 #include <iostream>然后硬编码标准要求的所有信息iostream发布。但是出于明显的实际原因,编译器通常不会这样做。它们允许独立团队开发标准库。

无论如何,如果 C++ 编译器包含 #define NULL (void *)0在它自己的头文件中,结果发生了一些不合格的事情,那么编译器显然是不合格的。如果没有任何不符合的情况发生,那么就没有问题。

我不知道您引用的文字会将其“邪恶”评论指向谁。如果它是针对编译器供应商告诉他们不要“邪恶”并淘汰不合格的编译器,我想我们无法反驳。

关于c++ - 表达式 "(ptr == 0) != (ptr == (void*)0)"真的可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22936924/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com