问题 “0xffffffff00000000”是否表示32位和64位编译之间的混淆?


我用64位编译了Qt。我的代码也是用64位编译的。我将(指针)成员变量初始化为零。当我检查它时,XCode告诉我它的值不是0而是0xffffffff00000000。

这是32到64之间混淆的标志吗?当库和我的代码都有'g ++ .. -arch x86_64 -Xarch_x86_64 ..'时,32位初始化如何进入可执行文件?万一重要的是,我在Snow Leopard上。

----开始,编辑----

我很欣赏在这些年之后发现,当一个指针为指针分配0时,标准不会强加值0x00..00,但在这种情况下这不是问题。

#include <stdio.h>

int main()
{
    const char * c = "Foo";
    printf("Pointers in this executable use %lu bytes.\n", sizeof(c));
    void * z = 0;
    printf("A zero pointer in this executable is %p\n", z);
}

如果我将上面的代码保存在'32_or_64.cpp'中,然后用'g ++ -arch i386 32_or_64.cpp'编译它,我得到

此可执行文件中的指针使用4个字节。
此可执行文件中的零指针是0x0

如果我用'g ++ -arch x86_64 32_or_64.cpp'编译它,我得到

此可执行文件中的指针使用8个字节。
此可执行文件中的零指针是0x0

如果您认为这不能确定我的特定配置上的0不应该让我在x86_64中调试时看到正好0,请指出它。否则,辩论'null'是一个很好的讨论,但在这个线程中是一个无关紧要的讨论。

----结束,编辑----


9335
2017-07-13 22:58


起源

您是否正在调试优化的发布版本?如果是这样,调试器可能会混淆并查看错误的位置。优化的代码严重混淆了调试器。 - Adam Rosenfield
不,构建是一个调试版本。成员变量由Classname :: Classname():abc(0){}初始化。在成员函数Classname :: myfunction()中,我问是否(abc){..} else {..},不应该像往常一样进行abc测试(除非已经设置,否则避免取消引用abc)?谈到abc(0)在某些平台上分配abc以外的任何东西,除了纯0x0000..0000之外,让我大吃一惊。使用零的精确值的全部意义是不能尽可能有效地测试指针是否为零,即不与某些预定值进行比较? - Calaf
它也可能是内存损坏的迹象。你用Guard Malloc运行程序了吗? - zneak


答案:


更新:根据π的编辑,这个解释似乎是假的。但无论如何你可能会发现它很有趣。


在类C语言中,指针值写为 0 在源代码中只是用于指定a的约定 空指针。空指针是一个保证不指向任何对象的指针,并且它被定义为测试等于整数零,但它不需要具有与整数零相同的内部表示。空指针可以有多种表示形式,具体取决于体系结构,甚至指针的类型。

指某东西的用途 0 意思是“空指针”也许是一个不幸的约定;它引起的混乱程度可能最好用Steve Summit的长度来表示 C编程语言FAQ 就此主题而言。

我认为,hexa的评论是难以理解这一惯例的证据。麻烦的是有三个想法要分开:

  • 概念 空指针:与指向任何对象的指针不同的指针。
  • 表示 一台机器上的空指针(在某些情况下由地址0x00000000,但这不是你可以或应该依赖的东西)。
  • 你怎么能 创建 和 测试 C语言中的空指针(使用 空指针常量 喜欢 0 要么 NULL)。

这是C ++标准,第4.10节:

一个 空指针常量 是整数类型的整数常量表达式rvalue,其计算结果为零。空指针常量可以转换为指针类型;结果是 空指针值 该类型的,并且可以与指向对象的指针或指向函数类型的指针的每个其他值区分开来。相同类型的两个空指针值应相等。

这可以保证您可以使用常量创建空指针 0,并通过比较测试指针是否为空 0,但没有说明空指针的机器表示。


10
2017-07-13 23:20



据我所知,在C ++中,NULL总是为0.或者我错了? - Vinicius Kamakura
@ hexa- C ++中的文字0表示空指针,但不要求它 实施 作为字面值0.我所知道的所有实现都使用零值来实现空指针,但这并不意味着您无法构建不执行此操作的兼容C ++实现。 - templatetypedef
@hexa - 我认为答案解释得很好,但也许可以稍微说一点:是的,在 语言 C ++,#define NULL为0,0用于表示空指针。但这并不意味着当编译器和链接器完成代码时,设置为null的指针将具有值0.这就是Gareth在区分空指针的概念和表示时所得到的。 - Marc
@Marc他在我发表评论后补充了这一切。我不知道的 表示 他提到的具体是实施。 - Vinicius Kamakura
不,它是实现定义的。 (C ++标准§5.2.10.4:“指针可以显式转换为足以容纳它的任何整数类型。映射函数是实现定义的。”) - Gareth Rees


完全可能你的 this 指针未指向正确的内存。如果您的程序表现出其他未定义的行为,那么这很可能就是随机垃圾内存。


0
2017-07-14 16:55