- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我在 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 achar*
toNULL
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/
我正在尝试在两个表之间进行空间连接: 表 1:397265 个特征(在 geom 字段上有 gist 索引) 表 2:73 个特征(在 geom 字段上有 gist 索引) 表 1 和表 2 具有相同
我正在尝试在两个表之间进行空间连接: 表 1:397265 个特征(在 geom 字段上有 gist 索引) 表 2:73 个特征(在 geom 字段上有 gist 索引) 表 1 和表 2 具有相同
枚举类型的值是该类型的静态变量。 据我所知,变量是由引用变量引用的,但没有新的运算符来实例化枚举对象。但这就像初始化数组一样吗? 这是对还是错? 最佳答案 是的,枚举类型的文字是 public sta
我阅读了有关关闭 zsh 自动更正以完成命令的所有提示。但是,它们并没有完全发挥作用。我试过 DISABLE_CORRECTION="true", unsetopt correct, unsetopt
我知道这个问题是 answered before ,但给出的答案并不是完整的故事: 我进入了 Firefox 的 Options->Content 并删除了除德语/德国之外的所有语言,navigato
我知道用汇编语言编写任何内容或将汇编语言添加到任何程序都会损害其可移植性。但是,有多糟糕呢?我的意思是,现在基本上所有 PC 都是 x86 或 x64,对吧?那么,如果我将汇编嵌入到 C 程序中,为什
我正计划构建一个 Web 服务客户端,它始终检查数据库中的某些记录,并根据数据库内容的结果在每个时刻及时执行某些决策。 所以我在想,我怎样才能让客户端一直运行呢? 我唯一想到的就是无限循环。像这样的东
我无法获取小部件的实际背景颜色。在我的特殊情况下,我在使用 QTabWidget 中的小部件时遇到了问题。 这是在 Windows7 上。所以经典小部件有一些灰色背景,而选项卡中的小部件通常用白色背景
请不要将我指向How to wrap preference title?因为它不适用于(正如我评论的那样)您使用 @strings/ 的情况对 strings.xml 文件的引用。 如果你使用 and
情况如下: 已知hdfs是仅附加的(本身没有更新)。 配置单元将数据写入其位于hdfs中的仓库。 可以在配置单元中执行更新 这意味着写入了新数据,旧数据应该以某种方式标记为已弃用,然后在某个时间将其清
在javascript中删除cookies的方法是将过期日期设置为过去。现在这实际上并没有删除 cookie,至少在 Firefox 中是这样。这只是意味着 cookie 将在浏览器关闭时被删除。 这
我需要终止一个卡住的线程,我将 IsBackground 设置为 true 但它仍然存在。线程的属性: ThreadState = AbortRequested IsBackground = true
在逻辑中,以及在 *ahem* 正确设计的编程语言中,将 boolean 值与 true 进行比较总是多余的,即 a == True 应该简单地替换为 a 。 (类似地, a == False 由 n
我一直在努力寻找一个好的定义,并理解线程到底是什么。 看来我一定错过了一些明显的东西,但是每次我读到什么是线程时,它几乎是一个循环定义,la“线程是一个执行线程”或“一种划分运行任务的方法” ”。呃呃
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
是否可以在 MAC 上以真正的全屏模式运行 IntelliJ Idea? 没有工具栏、侧边栏、按钮,只有代码。 如果可以,请告诉我。 最佳答案 您可以通过禁用以下项目在 View 菜单中执行此操作:
考虑以下代码: case class Vector3(var x: Float, var y: Float, var z: Float) { def add(v: Vector3): Unit =
我试图确认这个说法是否属实: 模型包括: 持久层:本质上是 DAO + 表示表的类 + DTO 服务层:DAOS + 一些逻辑的组合 您能否也引用/支持您的回答?我相信我在Spring Framewo
给定代码: #include struct X {}; struct Y1: virtual X {}; struct Y2: virtual X {}; struct Y3: virtual X
从这个其他QUESTION他们谈论 Bjarne Stroustrup 是如何说的,就像比 int 窄的整数数据类型(例如 short)被提升为 int,float 被提升为 double。但是,与i
我是一名优秀的程序员,十分优秀!