为什么我不能使用 '0x80000000' 来初始化一个 int 数组?
Why can't I use '0x80000000' to initialize an array of int?
#include<iostream>
int main()
{
int arr[1] = {0x80000000};
std::cout<<arr[0]<<"\n";
return 0;
}
以上代码会出现如下错误:
error: narrowing conversion of ‘2147483648u’ from ‘unsigned int’ to
‘int’ inside { } [-Wnarrowing] int arr[1] = {0x80000000};
但下面的代码可以完美运行:
#include<iostream>
int main()
{
int arr[1];
arr[0] = 0x80000000;
std::cout<<arr[0]<<"\n";
return 0;
}
所以我的问题是:为什么我不能使用'0x80000000'来初始化int
的数组?
因为这里 arr[0] = 0x80000000;
编译器执行强制转换(我们在这里谈论 int=32 位),这是实现定义的(取决于编译器)。您也可能会在某些编译器上收到警告。
但是编译器无法在初始化时进行强制转换,因为它直接将数组映射到内存。
0x80000000
不能放在这里 int
,所以它是一个 integer literal with type unsigned int
. For initialization, implicit conversion is needed, but other than assignment, implicit conversions are limited, i.e. narrowing conversions are prohibited in list initialization (C++11 起):
list-initialization limits the allowed implicit conversions by prohibiting the following:
- ...
- conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type
关于隐式转换的行为,即赋值中的 integral conversions:
If the destination type is signed, the value does not change if the source integer can be represented in the destination type. Otherwise the result is implementation-defined.
超出范围的转换行为是实现定义的,例如它可能会根据表示规则环绕(通常是 2 的补码)。
它没有"work perfectly"。当您使用静默允许截断的构造时,它可能 编译 ,但这并不意味着不会发生截断。您仍然会得到错误的结果,因为您的值不适合 signed int
,在这种情况下,编译器不会帮助您发现错误。
记住; "compiles" != "works".
#include<iostream>
int main()
{
int arr[1] = {0x80000000};
std::cout<<arr[0]<<"\n";
return 0;
}
以上代码会出现如下错误:
error: narrowing conversion of ‘2147483648u’ from ‘unsigned int’ to ‘int’ inside { } [-Wnarrowing] int arr[1] = {0x80000000};
但下面的代码可以完美运行:
#include<iostream>
int main()
{
int arr[1];
arr[0] = 0x80000000;
std::cout<<arr[0]<<"\n";
return 0;
}
所以我的问题是:为什么我不能使用'0x80000000'来初始化int
的数组?
因为这里 arr[0] = 0x80000000;
编译器执行强制转换(我们在这里谈论 int=32 位),这是实现定义的(取决于编译器)。您也可能会在某些编译器上收到警告。
但是编译器无法在初始化时进行强制转换,因为它直接将数组映射到内存。
0x80000000
不能放在这里 int
,所以它是一个 integer literal with type unsigned int
. For initialization, implicit conversion is needed, but other than assignment, implicit conversions are limited, i.e. narrowing conversions are prohibited in list initialization (C++11 起):
list-initialization limits the allowed implicit conversions by prohibiting the following:
- ...
- conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type
关于隐式转换的行为,即赋值中的 integral conversions:
If the destination type is signed, the value does not change if the source integer can be represented in the destination type. Otherwise the result is implementation-defined.
超出范围的转换行为是实现定义的,例如它可能会根据表示规则环绕(通常是 2 的补码)。
它没有"work perfectly"。当您使用静默允许截断的构造时,它可能 编译 ,但这并不意味着不会发生截断。您仍然会得到错误的结果,因为您的值不适合 signed int
,在这种情况下,编译器不会帮助您发现错误。
记住; "compiles" != "works".