printf会导致未定义的行为吗?

int main() { unsigned int i = 12; printf("%lu", i); // This yields a compiler warning } 

在32位平台上,使用带有%lu的int的printf导致垃圾吗?

只有声明“32位平台”并不意味着intlong都有32位,以及它们的unsigned对应物。

所以,是的,确实如果未unsingned long会发生这种情况,那么%lu unsingned long是否比unsigned int

但即使长度相等,类型也不兼容,所以forms上它是未定义的行为。

如果所需类型和给定类型不兼容,则表明存在未定义的行为。 传递vararg时,编译器传递带有值的类型信息,并在va_arg利用它是完全合法的(虽然我不知道有哪些做,可能是出于历史原因)。

至于你特定情况下的实际效果, "%lu"期望无符号长。 唯一兼容的其他类型是long,然后只有long的实际值是非负的。 将它传递给int是未定义的行为,尽管它可能有效。 (在大多数32位平台上, intlong具有相同的大小和表示。)

说实话,我不明白你为什么要使用%lu代替%u,因为你正在使用int。

对于无符号长整数,应该使用%lu(在其基本解释中)。

如果你的编译器使用(当然它在99%的情况下)int和long的不同存储大小,它很可能会打印垃圾。

例如,根据C标准,无符号int在存储大小“至少16位大小”方面是无符号整数,而无符号长整数是“至少32位大小”。

现在,我们以int为16位,long为32位为例,让我们考虑一个非典型的例子,在你运行程序时,内存全部归零。

值12在内存中表示为:

00000000 00001100

如果你用%u打印会导致12:

在适当的位置,如果指示printf打印为%lu,则会导致printf中的内存为:

00000000 00001100 00000000 00000000

对应于786432的长值

编辑:将变量的值传递给printf函数(而不是变量的指针(和大小))使代码仍然工作。 我之前的“解释”主要是为了解释为什么警告被提出以及为什么它“通常”是一种错误的方法。