C整数隐式转换
我试图理解以下转换的机制C整数隐式转换,c,type-conversion,integer,C,Type Conversion,Integer,我试图理解以下转换的机制 #include <stdio.h> #include <stdint.h> int main() { int a = 0xffffffff; printf("%d", a); // prints -1 return 0; } #包括 #包括 int main(){ int a=0xffffffff; printf(“%d”,a);//prints-1 返回0; } 根据0xffff
#include <stdio.h>
#include <stdint.h>
int main() {
int a = 0xffffffff;
printf("%d", a); // prints -1
return 0;
}
#包括
#包括
int main(){
int a=0xffffffff;
printf(“%d”,a);//prints-1
返回0;
}
根据0xffffffff
的类型是unsigned int
。这可以通过执行printf(“%s”,0xffffffff)
轻松检查
现在,根据:
“整数提升是对任意值的隐式转换
秩小于或等于值的int[…]秩的整数类型
类型为int或无符号int。“
以及,如下文所述
“所有有符号整数类型的秩等于
对应的无符号整数类型“
因此提升适用,因为unsigned int
的排名与int
的排名相同
这种晋升被定义为
“If int可以表示原始类型的整个值范围
(或原始位字段的值范围),该值为
已转换为int类型。否则,该值将转换为无符号
int“
但是,这就是我不理解的,
int
不能表示无符号int
4294967295,但它仍然转换为int
。这种情况发生时没有任何狭窄警告。为什么会这样?由于常量0xffffffff
(假设int
为32位)的类型为无符号int
,用于初始化int
类型的对象,这涉及从无符号int
到int
的转换
C标准第6.3.1.3节描述了整数类型之间的转换:
1当整数类型的值转换为除\u Bool
以外的其他整数类型时,如果该值可以用新的
类型,它是不变的
2否则,如果新类型是无符号的,则通过重复地加上或减去一个以上的值来转换该值
可以在新类型中表示的最大值
直到值在新类型的范围内
3否则,新类型是有符号的,不能在其中表示值;要么结果是实现定义的
或者引发实施定义的信号
第3款适用于本案。所讨论的值不在目标类型的范围内,并且目标已签名。因此,将发生实现定义的转换
如果您使用gcc使用-Wconversion
标志进行编译,它将向您发出警告:
x1.c:6:5:警告:将无符号常量值转换为负整数[-Wsign conversion]
int a=0xffffffff;
此外:
这可以通过执行printf(“%s”,0xffffffff)来轻松检查代码>
这是因为%s
格式说明符需要一个指向以null结尾的字符串的字符*
。您要传递的值不是此类型,并且可能不是有效的内存地址
整数提升在这里也不适用,因为没有比int
或unsigned int
低秩类型的表达式,因为常量0xffffff
(假设int
为32位)具有类型unsigned int
,用于初始化int
类型的对象,这涉及从unsigned int
到int
的转换
C标准第6.3.1.3节描述了整数类型之间的转换:
1当整数类型的值转换为除\u Bool
以外的其他整数类型时,如果该值可以用新的
类型,它是不变的
2否则,如果新类型是无符号的,则通过重复地加上或减去一个以上的值来转换该值
可以在新类型中表示的最大值
直到值在新类型的范围内
3否则,新类型是有符号的,不能在其中表示值;要么结果是实现定义的
或者引发实施定义的信号
第3款适用于本案。所讨论的值不在目标类型的范围内,并且目标已签名。因此,将发生实现定义的转换
如果您使用gcc使用-Wconversion
标志进行编译,它将向您发出警告:
x1.c:6:5:警告:将无符号常量值转换为负整数[-Wsign conversion]
int a=0xffffffff;
此外:
这可以通过执行printf(“%s”,0xffffffff)来轻松检查代码>
这是因为%s
格式说明符需要一个指向以null结尾的字符串的字符*
。您要传递的值不是此类型,并且可能不是有效的内存地址
整数提升在这里也不适用,因为没有比int
或unsigned int
低秩的表达式。问题是,您正在转换(不是您,而是编译器代表您)一个无符号数(值0xffffffff
)转换为超出其有效值范围的有符号int
(您正试图将4294967296
转换为int
,但int
仅涵盖-2147483648
。+2147483647
)因此您得到未定义的行为
根据您使用的编译器(和体系结构),您可以获得不同的值,甚至由于溢出而产生异常。我猜你的编译器使用了2的补码,它只是将这个数字重新解释为它的等价二进制表示形式,即-1
(-1
在内部表示为四个字节0xff
一个af