【问题标题】:Is this constexpr integer not a null pointer constant?这个 constexpr 整数不是空指针常量吗?
【发布时间】:2012-11-21 12:31:32
【问题描述】:

考虑以下 C++11 程序及其在 GCC 4.7.2 中的结果:

int main()
{
   constexpr int i = 0;
   int* p = i;
}

// g++ -g -ggdb -Wall -Wextra -pedantic -std=c++11 t.cpp
// t.cpp: In function 'int main()':
// t.cpp:4:13: error: invalid conversion from 'int' to 'int*' [-fpermissive]
// t.cpp:4:9: warning: unused variable 'p' [-Wunused-variable]

按照标准:

[C++11: 4.10/1]:空指针常量是整数类型的整数常量表达式 (5.19) prvalue,其计算结果为零 [..]

5.19 是一团糟,我无法完全解析它,但我们不希望 i 满足这个标准并充当 空指针常量,因此不需要显式转换到int* 初始化p

如果我s/constexpr/const/ 并使用-ansi 而不是-std=c++11 编译,则编译成功。

【问题讨论】:

  • 我不希望它是一个空指针常量,主要是因为i 是一个左值。但是,由于该表达式在某种程度上涉及左值到右值的转换,并且在此之后,标准会生成一个常量表达式,因此我们可以合理地认为它是一个 NPC,尽管这可能是反常的。请注意,它会导致重载解决方案的混乱,尤其是。当您使用未知值时,例如。在模板中。顺便说一句,我不会把 gcc 作为基准,他们对常量的处理很糟糕。
  • 如果今天从头开始重新设计该语言,那么任何地方都需要nullptr,并且您将永远无法在没有强制转换的情况下将整数类型(常量或其他)分配给指针。我认为将其限制为文字 0 以实现向后兼容性是有意义的,使用更复杂的常量表达式是没有用的,它恰好作为空指针常量计算为零。
  • 请注意 Lippman 的 C++ 入门,第 5 版(涵盖 c++11)练习 2.32,这几乎是一回事。我认为 OP 有正确的答案,而 gcc 是这里的问题所在。有cmets吗?
  • @FlipMcF:在撰写本文时,委员会将此问题列为“待审核”。
  • 在解决提到的前 2.32 时困惑地来到这里。

标签: c++ c++11 constexpr


【解决方案1】:

[C++11: 5.19/3]:文字常量表达式是纯右值核心常量表达式,文字类型,但不是指针类型。 整型常量表达式是整型或无范围枚举类型的字面常量表达式。 [..]

还有:

[C++11: 3.9/10]: 类型是文字类型如果是

  • 标量类型;或
  • 引用类型;或
  • 具有以下所有属性的类类型(第 9 条):[..]
  • 文字类型的数组。

此时,我找不到该代码不合规的原因,因此我怀疑存在 GCC 错误。

但是,考虑到您在 4.10 中引用的段落被提议更改 (active issue #903),这可能是一个故意的错误,因此这实际上是不合规的代码。


如果我s/constexpr/const/ 并使用-ansi 而不是-std=c++11 编译,则编译成功。

整数常量表达式的定义在 C++03 中明确允许这种情况:

[C++03: 5.19/1]: [..] 整数常量表达式 只能涉及文字 (2.13)、枚举器、const 变量 或整数或枚举类型的静态数据成员使用常量表达式 (8.5)、整数或枚举类型的非类型模板参数和 sizeof 表达式进行初始化。 [..]

【讨论】:

  • 其实你的重点是错误的。你应该强调文字常量表达式,而int是文字类型。
  • 我认为你是对的,这是一个 GCC 错误。然而,那只是因为这实际上是当前标准中的一个缺陷。计划在下一次迭代中删除这个东西,只允许实际的文字零作为空指针常量(即没有像 1-1 这样的废话)
  • @R.MartinhoFernandes:啊,有趣!您有问题编号吗?
  • 供参考,this是相关的DR。
  • 你对自己说“你”的方式很奇怪。
猜你喜欢
  • 1970-01-01
  • 2014-12-16
  • 2019-10-06
  • 1970-01-01
  • 2015-01-27
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多