【发布时间】: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 时困惑地来到这里。