【问题标题】:Is "0xffffffff00000000" an indication of a mix-up between 32-bit and 64-bit compilations?“0xffffffff00000000”是否表示 32 位和 64 位编译之间存在混淆?
【发布时间】:2011-10-04 22:14:26
【问题描述】:

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

这是 32 和 64 混淆的迹象吗?当库和我的代码都具有“g++ .. -arch x86_64 -Xarch_x86_64 ..”时,32 位初始化如何潜入可执行文件?以防万一,我在雪豹上。

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

我很高兴在这么多年后发现,当将 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' 是一个精彩的讨论,但在此线程中无关紧要。

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

【问题讨论】:

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

标签: c++ xcode qt 32bit-64bit


【解决方案1】:

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


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

使用0 表示“空指针”可能是一种不幸的约定;史蒂夫峰会的C programming language FAQ 关于这个主题的长度可能最好地表明了它引起的混乱程度。

我认为,hexa 的评论证明了理解这个约定的困难。麻烦的是要分离三个想法:

  • 空指针的概念:与指向任何对象的指针不同的指针。
  • 机器上空指针的表示(在某些情况下是地址 0x00000000,但这不是您可以或不应该依赖的东西)。
  • 如何在类 C 语言中创建test空指针(通过使用空指针常量0或@ 987654326@)。

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

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

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

【讨论】:

  • 据我所知,在 C++ 中,NULL 始终为 0。还是我弄错了?
  • @hexa- C++ 中的字面量 0 代表空指针,但没有要求将其 实现 作为字面量值 0。我所知道的所有实现使用零值来实现空指针,但这并不意味着您不能构建不这样做的兼容 C++ 实现。
  • @hexa - 我认为答案很好地解释了它,但可能会略有不同:是的,在 language C++ 中,#define NULL 是 0 和 0用于表示空指针。但这并不意味着当编译器和链接器完成您的代码时,设置为 null 的指针将具有值 0。这就是 Gareth 在区分概念和空指针的表示时所得到的。
  • @Marc 他在我发表评论后添加了所有这些。我不知道他提到的 representation 是特定于实现的。
  • 不,它是实现定义的。 (C++ 标准 §5.2.10.4:“指针可以显式转换为任何大到足以容纳它的整数类型。映射函数是实现定义的。”)
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 2011-04-12
    • 2023-03-03
    • 2014-01-12
    • 2017-01-21
    • 2018-08-04
    • 2013-01-11
    相关资源
    最近更新 更多