从整数常量表达式转换为空指针 [英] Conversion from integral constant expression to null-pointer

查看:177
本文介绍了从整数常量表达式转换为空指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆