这个constexpr整数不是一个空指针常量吗?

8

考虑以下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]: 空指针常量是一个整数类型的整数常量表达式(prvalue),其评估结果为零。
5.19很混乱,我没能完全解析它,但我们不希望i满足这个条件并且作为空指针常量,因此在初始化p时不需要显式转换为int*吗?
如果我用constexpr替换const并使用-ansi而不是-std=c++11进行编译,则编译将成功。

我不认为它会是一个空指针常量,主要是因为i是一个左值。但由于表达式在某种程度上涉及左值到右值的转换,之后,标准使其成为常量表达式,我们可以合理地认为它是一个NPC,尽管可能是反常的。请注意,在重载解析中它会造成混乱,特别是当您在模板中使用未知值时。顺便说一句,我不会将gcc视为基准,在这里,他们对常量的处理方式很可怕。 - jpalecek
3
如果语言今天从头开始设计,那么nullptr将无处不在,并且您将永远无法将整数类型(常量或其他)分配给指针而不使用转换。为了保持向后兼容性,我认为仅将其限制为文字 0 是有意义的,没有必要将更复杂的常量表达式用作空指针常量,即使它恰好评估为零。 - Andrew Tomazos
1
请注意Lippman的C++ Primer第5版(涵盖c++11)练习2.32,这几乎是相同的问题。我认为OP已经给出了正确的答案,gcc可能是在这里出现问题的原因。有任何评论吗? - FlipMcF
@FlipMcF:在撰写本文时,委员会仍将此问题列为“待审核”。 - Lightness Races in Orbit
在解决所提到的2.32练习时,我感到困惑,来到这里寻求帮助。 - funct7
1个回答

8
:文字常量表达式是字面类型的prvalue核心常量表达式,但不是指针类型。整数常量表达式是整数或未作用域枚举类型的文字常量表达式。[..]
而: :如果以下条件都满足,则类型是文字类型:
  • 标量类型;或
  • 引用类型;或
  • 具有所有以下属性的类类型(第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表达式。[..]

1
我认为你说得对,这是GCC的一个bug。然而,这只是因为当前标准中存在一个缺陷。计划在下一次迭代中删除此内容,并仅允许实际的字面零作为空指针常量(即没有像1-1之类的无意义内容)。 - R. Martinho Fernandes
@R.MartinhoFernandes:啊,有趣!你有问题编号吗? - Lightness Races in Orbit
4
参考文献,这是相关的缺陷报告(DR)的链接。 - Xeo
@R.MartinhoFernandes:好的,现在怎么样了? - Lightness Races in Orbit
1
奇怪,你对自己说“你”。 - Johannes Schaub - litb
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接