【问题标题】:Is this a nullptr?这是一个空指针吗?
【发布时间】:2014-05-13 18:29:44
【问题描述】:

阅读this问答,我认为p不应该是nullptr,即使x0。我理解对了吗?

int main()
{
    int x = 0;

    std::cin >> x; // Enter `0`

    void *p = (void *)x; // or: void *p = reinterpret_cast<void*>(x);


    if (!p)
        std::cout << "p is nullptr" << std::endl;
}

在标准输入中输入0 后,消息p is nullptr 将显示在我的GCC 中。 根据link,它不应该评估为nullptr,但结果不是我的预期。

代码是未定义的行为吗?或未指定的结果?为什么它评估为nullptr

【问题讨论】:

  • 你正在将一个值为 0 的 int 投射到一个 void * 指针(对于所有意图和目的,它也可能只是一个美化的并且可能更广泛的 int) - 仍然0 的值。您希望p 具有什么值?
  • if 确实是在测试 p == 0 是否,它当然可以。 0 == nullptr 是否是一个更有趣的问题(VC++2012 说它确实如此,因为它的价值)。
  • nullptr 是什么,你在说 C++/CLI 吗? NULL 与零一样为零,一些 C++ 编码人员甚至避免使用 NULL,因为它太不确定(而是测试 0 或 0L)。
  • @dlf:VC++2012 所说的无关紧要。 规范说的是什么。
  • @dlf 不,实际上是相反的。 0 == nullptr,顾名思义。问题仅仅在于将int0 转换为指针是否也等于它。在 OP 的代码中似乎是这样,但有一些例子(虽然我现在找不到链接)不是这种情况(即空指针由非零位模式表示)。

标签: c++


【解决方案1】:

来自 C++11 5.2.10/5 Reinterpret cast [expr.reinterpret.cast](强调添加):

整数类型或枚举类型的值可以显式 转换为指针。转换为足够整数的指针 大小(如果实现中存在这样的大小)并返回相同的大小 指针类型将具有其原始值; 指针之间的映射 并且整数是由实现定义的

来自 5.2.10/4 的相关位:

std::nullptr_t 类型的值可以转换为整数类型; 转换与转换具有相同的含义和有效性 (void*)0 为整型。 [注意:reinterpret_cast 不能 用于将任何类型的值转换为 std::nullptr_t 类型。 -结尾 注意]

【讨论】:

    【解决方案2】:

    ISO/IEC 14882:2011 §4.10/1(以及针对成员指针的 §4.11/1)仅表示 _constant 整数表达式,它整数类型的整数常量表达式右值,其计算结果为零是一个空指针常量。

    对于整数,唯一的要求是在 §5.2.10/5 中,它说:

    转换为足够大小的整数(如果实现中存在这样的整数)并返回相同指针类型的指针将具有其原始值;指针和整数之间的映射是由实现定义的。

    因此,整数值0是否转换为空指针也是实现定义的。在大多数实现中它确实如此,因为这样更容易。

    【讨论】:

    • 第一句复制粘贴错误? “一个常量整数表达式那个整数常量表达式”看起来不对。
    【解决方案3】:

    让我们试着回答你的问题:

    有可能reinterpret_cast&lt;void*&gt;(x) != nullptr 如果int x = 0。但这不是强制性的。实际上,reinterpret_cast&lt;void*&gt;(x) == nullptr 在大多数平台中,但取决于其中一个是未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-18
      • 2023-03-07
      • 2013-05-09
      相关资源
      最近更新 更多