C++ 为什么`int a=-1;printf(';%lld';,a)`输出4294967295?

C++ 为什么`int a=-1;printf(';%lld';,a)`输出4294967295?,c++,C++,在,我看到%lld格式需要long-long-int格式,当类型不一致时,它将被提升。当-1升级为long-long-int时,它应该是-1;printf(“%lld”,a)output 4294967295?考虑编写表达式longtest=0x100000000。很明显,程序员希望在变量test中指定一个大于int的值。这就是为什么对于int类型来说太大的值会被提升为更大的类型。(见附件)。在本例中,您的文字0xffffffff太大,无法放入有符号整数值中,因此它被提升为长整数。这个long被

在,我看到
%lld
格式需要long-long-int格式,当类型不一致时,它将被提升。当-1升级为long-long-int时,它应该是-1;printf(“%lld”,a)output 4294967295?

考虑编写表达式
longtest=0x100000000
。很明显,程序员希望在变量
test
中指定一个大于
int
的值。这就是为什么对于int类型来说太大的值会被提升为更大的类型。(见附件)。在本例中,您的文字
0xffffffff
太大,无法放入有符号整数值中,因此它被提升为长整数。这个long被传递给printf,printf打印它传递的值

当类型不一致时,将对其进行升级

事实并非如此。参数的类型必须为
long-long-int
,否则行为未定义。而且“cplusplus.com”不是“官方文件”,它是一个私营网站


0xffffffff
的类型由实现定义。在常见的LLP64实现中,它将具有类型
long
,并提供定义良好的行为,这就是您所看到的。在其他实现中,它可能是
长的
,甚至是另一种类型,因此您可以看到任何东西。

类型0xFFFFFF只能是有符号32位整数类型,只有在该类型可以容纳如此大的正值的平台上。在具有32位整数的平台上,
0xFFFFFF
具有类型
无符号整数
,当转换为64位有符号整数类型时,不会将其视为
-1
。@tomkarze,但即使我使用
int a=-1;PrtTF(“%LLD”,A),其输出仍然是429 4967。5,使用错误类型的参数,对于特定的格式说明符调用未定义的行为(UB),如果转换规范无效,则行为未定义,这是C++中的。standard@jameslahm您的类型不匹配。编译器应该对此发出警告(请尝试提高警告级别)。在参数列表中将其更改为
(long-long-int)a
,您应该会看到不同之处。对于可变函数,没有给出参数类型的原型,因此只能得到标准的提升。特别是,
int
保留
int
unsigned int
保留
unsigned int
;printf(“%lld”,a)
,其输出仍然是4294967295。在这种情况下,输出是相同的,但原因完全不同。这里的问题是函数
printf
可以接受任何类型的参数,并使用格式字符串来确定传递给它的参数类型。在本例中,您告诉它“我正在给您传递一个long”,将实际传递一个int。您可以通过显式地将您的值转换为正确的类型
printf(“%lld”,(long-long-int)a)来修复此问题。这就是为什么许多C项目都使用标志
-Wall-Werror
编译的原因,这将防止您犯此错误。非常感谢,我明白了。但是当参数类型不一致时,是否应该将其提升为
long
?这里我传递一个值为-1的int,如果提升,它应该是一个值为-1的
long
,输出也应该是-1。这里没有提升。“文本的类型”没有提升作为一个步骤。@M.M您希望
0xffffffff
将符号扩展到
0xffffffffff
,而这根本不是发生的情况。如果
0xFFFFFF
大于
int
所能容纳的值,则编译器使用下一个最大的类型(
long
long-long
,具体取决于平台),并按该类型解释
0xFFFFFF
,这将是
0x00000000ffffffff
,实际上是
4294967295
,而不是
-1
。谢谢,但我在正式文档中看到了“(如果使用不同的类型,将执行适当的类型升级或转换,如果允许)”。我也尝试
shortinta=-1;print(“%d”,a)
,其输出为-1,表明它已升级为int。@jameslahm这不是官方文档,该语句是错误的。官方文件是ISO标准。“代码>短代码/代码>示例也不同(整数提升适用于变量函数的参数,但这与Prtf格式字符串无关),我一直在查看C++标准PDF,找不到任何类似的东西。据我所知,提升只发生在函数参数类型不匹配上。@dgrandm您的“知识”是错误的,提升与函数参数不匹配无关。积分提升在C++17标准的[conv.prom]部分有描述(然后其他部分指定积分提升发生的时间,您可以通过搜索该术语的用法来找到)@M.M,非常感谢,我明白了。