#include<iostream>
int main()
{
int arr[1];
arr[0] = 0x80000000;
std::cout<<arr[0]<<"\n";
return 0;
}
上面的代码会出现以下错误:
错误:缩小'2147483648u'从'unsigned int'转换为 'int'在{} [-Wnarrowing] int arr [1] = {0x80000000};
但以下代码完美无缺:
int
所以我的问题是:为什么我不能使用&#39; 0x80000000&#39;初始化一个geo.wifi.uri
?
答案 0 :(得分:7)
0x80000000
此处不适合int
,因此它是integer literal类型为unsigned int
的{{3}}。对于初始化,需要进行隐式转换,但除了赋值之外,隐式转换是有限的,即list initialization中禁止缩小转换(自C ++ 11起):
list-initialization通过禁止以下内容来限制允许的隐式转换:
- ...
- 从整数或无范围枚举类型转换为不能表示原始值的整数类型,除非source是一个常量表达式,其值可以精确地存储在目标类型中
关于隐式转换的行为,即分配中的integral conversions:
如果目标类型已签名,则如果源整数可以在目标类型中表示,则值不会更改。否则结果是实现定义的。
超出范围转换的行为是实现定义的,例如它可以根据表示的规则(通常为2的补码)进行包装。
答案 1 :(得分:2)
它没有&#34;完美地工作&#34;。当您使用静默允许截断的构造时,它可能编译,但这并不意味着不会发生截断。您仍然会得到错误的结果,因为您的价值不适合signed int
,编译器在这种情况下无法帮助您发现您的错误。
记住; &#34;编译&#34; !=&#34;工作&#34;。
答案 2 :(得分:1)
因为这里arr[0] = 0x80000000;
编译器执行强制转换(我们在这里讨论int = 32位),这是实现定义的(取决于编译器)。您也可能会收到某些编译器的警告。
但是初始化时编译器无法执行转换,因为它直接将数组映射到内存。