从整型常量表达式到空指针的转换

2024-01-06

考虑以下代码:

#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 的编译时间常数吗?

PS 使用 g++ v 5.1.0 检查,它接受除f(i);在 c++11 和 c++14 模式下 PPS 使用 clang 3.7 检查,它拒绝 c++11 和 c++14 模式下除文字 0 之外的所有变体


这是一个海湾合作委员会错误。缺陷报告 903:值相关的整型空指针常量 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#903这是针对 C++11 的缺陷报告(它具有 CD3 状态),使得只有整数文字0被视为空指针常量。

它改变了部分4.10[conv.ptr] 段落1除其他变化外:

空指针常量是整数类型的整型常量表达式 (5.19 [expr.const]) 纯右值,其计算结果为零 [...]

to:

空指针常量是一个整数文字 (2.14.2 [lex.icon]),其值为零 [...]

这被列为与 C++03 不兼容,来自章节C.2.2第 4 条:标准转换[diff.cpp03.conv]其中说:

Change:只有文字是整型空指针常量
理由:消除与模板的令人惊讶的交互 常量表达式
对原始特征的影响:有效的 C++ 2003 代码可能无法编译或 在此国际标准中产生不同的结果,因为 下面的例子说明:

void f(void *); // #1
void f(...); // #2
template<int N> void g() {
  f(0*N); // calls #2; used to call #1
}

以下 gcc 错误报告[C++11] [DR 903] 零值整数常量表达式应该优先转换为指针 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52145显示 gcc 团队最初认为这是 C++17 的更改,但后来将其更改为在 C++11 中生效。

我们可以在 gcc 的 head 修订版中看到(6.0)这是固定的(现场观看 http://melpon.org/wandbox/permlink/bv11uodgGHlloJRE)并为 clang 所做的所有情况生成诊断:

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
    ~~^~~
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从整型常量表达式到空指针的转换 的相关文章

随机推荐