从整数常量表达式转换为空指针 [英] Conversion from integral constant expression to null-pointer
问题描述
请考虑以下代码:
#include <memory>
void f( std::shared_ptr<int> ) {}
int main()
{
f( 0 ); // compiles fine in gcc and clang
f( 1 - 1 ); // compiles fine in gcc, fails in clang
constexpr int i = 0;
f( i ); // fails to compile in gcc and clang
f( i - 0 ); // compiles fine in gcc, fails in clang
}
为什么只有 f(i)
无法编译,但 i
应该被计算为编译时常数值为0?
why only f( i )
fails to compile, though i
should be evaluated as compile time constant with value 0?
PS使用g ++ v 5.1.0进行检查,它接受c ++ 11和c ++中除 f(i);
14模式
用clang 3.7检查PPS,它拒绝c ++ 11和c ++ 14模式中除文字0之外的所有变体
PS checked with g++ v 5.1.0, it accepts all variants except f(i);
in both c++11 and c++14 mode
PPS checked with clang 3.7, it rejects all variants except literal 0 in both c++11 and c++14 mode
推荐答案
这是一个gcc错误。 缺陷报告903:值依赖的集成空指针常量< a>其是针对C ++ 11(它具有CD3状态)的缺陷报告,使得仅考虑整数文本 0
空指针常量。
This is a gcc bug. Defect report 903: Value-dependent integral null pointer constants which is a defect report against C++11(it has CD3 status), makes it so that only an integer literal 0
is considered a null pointer constant.
更改了 4.10
[conv.ptr]段 1
其他更改:
It changed section 4.10
[conv.ptr] paragraph 1
amongst other changes from:
空指针常量是一个整数常数表达式(5.19 [expr.const])整型的prvalue [...]
A null pointer constant is an integral constant expression (5.19 [expr.const]) prvalue of integer type that evaluates to zero [...]
到:
空指针常数是值为零的整数文字(2.14.2 [lex.icon])[...]
A null pointer constant is an integer literal (2.14.2 [lex.icon]) with value zero [...]
这是被列为与C ++ 03不兼容,从 C.2.2
第4条:标准转换 [diff.cpp03.conv] 其中说::
This is listed as an incompatibility against C++03, from section C.2.2
Clause 4: standard conversions [diff.cpp03.conv] which says:
更改:只有文字是整数空指针常数
原因:使用模板和
常量表达式删除令人惊讶的交互
对原始特征的影响:有效的C ++ 2003代码可能无法编译或
在此国际标准中产生不同的结果,因为
以下示例说明:
Change: Only literals are integer null pointer constants
Rationale: Removing surprising interactions with templates and constant expressions
Effect on original feature: Valid C++ 2003 code may fail to compile or produce different results in this International Standard, as the following example illustrates:
void f(void *); // #1
void f(...); // #2
template<int N> void g() {
f(0*N); // calls #2; used to call #1
}
错误报告 [C ++ 11] [DR 903]零值整数常数表达式应喜欢转换到指针表明gcc团队最初认为这是一个C + + 17的变化,但后来更改为在C ++ 11中生效。
The following gcc bug report [C++11] [DR 903] zero-valued integer constant expression should prefer conversion to pointer shows that the gcc team originally thought this was a C++17 change but later changed it to be in effect in C++11.
我们可以在gcc( 6.0 )的head修订版中看到这是修复的( 查看它现场 )并为所有clang所做的诊断:
We can see in the head revision of gcc(6.0) this is fixed (see it live) and produces a diagnostic for all the cases clang does:
error: could not convert '(1 - 1)' from 'int' to 'std::shared_ptr<int>'
f( 1 - 1 ); // compiles fine in gcc, fails in clang
~~^~~
error: could not convert 'i' from 'const int' to 'std::shared_ptr<int>'
f( i ); // fails to compile in gcc and clang
^
error: could not convert '(0 - 0)' from 'int' to 'std::shared_ptr<int>'
f( i - 0 ); // compiles fine in gcc, fails in clang
~~^~~
这篇关于从整数常量表达式转换为空指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!