Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ nullptr能否转换为uintptr\t?不同的编译器不同意_C++_C++11_Gcc_Visual C++_Clang - Fatal编程技术网

C++ nullptr能否转换为uintptr\t?不同的编译器不同意

C++ nullptr能否转换为uintptr\t?不同的编译器不同意,c++,c++11,gcc,visual-c++,clang,C++,C++11,Gcc,Visual C++,Clang,考虑一下这个计划: #include <cstdint> using my_time_t = uintptr_t; int main() { const my_time_t t = my_time_t(nullptr); } #包括 使用我的时间=uintptr; int main(){ const my_time_t=my_time_t(nullptr); } 无法使用msvc v19.24进行编译: <source>(5): error C2440: '

考虑一下这个计划:

#include <cstdint>
using my_time_t = uintptr_t;

int main() {
    const my_time_t t = my_time_t(nullptr);
}
#包括
使用我的时间=uintptr;
int main(){
const my_time_t=my_time_t(nullptr);
}
无法使用msvc v19.24进行编译:

<source>(5): error C2440: '<function-style-cast>': cannot convert from 'nullptr' to 'my_time_t'
<source>(5): note: A native nullptr can only be converted to bool or, using reinterpret_cast, to an integral type
<source>(5): error C2789: 't': an object of const-qualified type must be initialized
<source>(5): note: see declaration of 't'

Compiler returned: 2
(5):错误C2440:'':无法从'nullptr'转换为'my\u time\t'
(5) :注意:本机nullptr只能转换为bool,或者使用reinterpret_cast转换为整型
(5) :错误C2789:'t':必须初始化常量限定类型的对象
(5) :注:见“t”的声明
返回的编译器:2
但是clang(9.0.1)和gcc(9.2.1)没有任何错误地“吃”这段代码

我喜欢MSVC的行为,但它是否得到了标准的确认? 换句话说,它是clang/gcc中的bug还是可以解释的
这是gcc/clang的正确行为的标准?

所有行为都符合标准(参考C++的草案n4659)

nullptr
在[lex.nullptr]中定义为:

指针文本是关键字nullptr。它是std::nullptr\t类型的PR值。[注意:…,此类型的PRV值为 空指针常量,可以转换为空指针值或空成员指针值。]

即使注释是非规范性的,这一条也清楚地表明,对于标准,
nullptr
预计将被转换为null指针

我们随后在[conv.ptr]中发现:

空指针常量是一个值为零的整型文字或一个类型为std::nullptr\t的prvalue。A. 空指针常量可以转换为指针类型。。。。整数类型的空指针常量可以 将转换为std::nullptr\t类型的prvalue

这里,标准要求的是
0
可以转换为
std::nullptr\t
,并且
nullptr
可以转换为任何指针类型

我的理解是,该标准对
nullptr
是否可以直接转换为整数类型没有要求。从那时起:

  • MSVC有严格的阅读和禁止转换
  • Clang和gcc的行为就像涉及到中间
    void*
    转换一样

尽管我在这篇文章(从2014年起)中没有明确提到禁止将
std::nullptr\t
转换为整数类型,但也没有提到允许这样的转换

但是,明确提到了从
std::nullptr\u t
转换为
bool
的情况:

4.12布尔转换
算术值、非范围枚举、指针或指向成员类型的指针可以转换为 bool类型的pr值。零值、空指针值或空成员 指针值被转换为false;任何其他值都将转换为 对。对于直接初始化(8.5),类型为 std::nullptr_t可以转换为bool类型的prvalue;这个 结果值为false

此外,本文件草案中唯一提到从
std::nullptr\u t
转换为整数类型的地方是“重新解释转换”部分:

5.2.10重新解释演员阵容

(4) 指针可以显式转换为任何足以容纳它的整数类型。映射函数是 实现定义。[注:这并不奇怪 那些知道底层机器的寻址结构的人- 结束说明]std::nullptr\t类型的值可以转换为 积分型;转换的含义和有效性与 将(void*)0转换为整数类型。[注:重新解释演员阵容] 无法用于将任何类型的值转换为类型 std::nullptr_t.-结束注释]

因此,从这两个观察结果中,我们可以(IMHO)合理地推测
MSVC
编译器是正确的

编辑:然而,您使用“功能符号转换”实际上可能表明相反的情况!
MSVC
编译器在使用C样式强制转换时没有问题,例如:

uintptr\u t answer=(uintptr\u t)(nullptr);
但是(就像在你的代码中一样),它抱怨:

uintpttr\u t answer=uintpttr\u t(nullptr);//错误C2440:'':无法从'nullptr'转换为'uintptr\t'
然而,根据同一标准草案:

5.2.3显式类型转换(函数表示法)
(1) 后面跟着一个简单的类型说明符(7.1.6.2)或类型名说明符(14.6) 由括号中的表达式列表构造指定 输入给定的表达式列表。如果表达式列表是单个 表达式,则类型转换表达式是等效的(在 定义,以及(如果定义有意义)对应的类型 表达式(5.4)


“对应的强制转换表达式(5.4)”可以指C型强制转换。

在我看来,MSVC的行为不符合标准

我的回答是基于C++17(草案N4659),但C++14和C++11有相同的措辞

my\u time\u t(nullptr)
是一个后缀表达式,因为
my\u time\u t
是一个类型,
(nullptr)
是括号内初始值设定项列表中的单个表达式,所以它完全等同于显式强制转换表达式。()

显式CAST尝试了几种不同的C++ C++(带有扩展),尤其是RealTytCase。()在

重新解释强制转换之前尝试的强制转换是
常量强制转换
静态强制转换
(带有扩展和组合),但这些都不能将
std::nullptr_t
强制转换为整型

但是
reinterpret\u cast(nullptr)
应该会成功,因为
std::nullptr\u t
类型的值可以像通过
reinterpret\u cast((void*)0)
一样转换为整数类型,这是可能的,因为
my\u time\u t=std
const my_time_t t = (my_time_t)nullptr;