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

时间:2014-04-25 07:50:37

标签: c++ c

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

在32位平台上,使用带有printf结果的int的%lu是否会导致垃圾?

3 个答案:

答案 0 :(得分:8)

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

所以,是的,如果unsingned long%lu的作用超过unsigned int,确实会发生这种情况。

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

答案 1 :(得分:4)

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

至于您特定情况下的实际效果,"%lu" 期待一个未签名的长期。唯一的另一种类型 兼容性很长,然后只有实际值 长期是非负面的。传递int未定义 行为,虽然它可能有效。 (在大多数32位平台上, intlong具有相同的大小和代表性。)

答案 2 :(得分:1)

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

对于无符号长整数,应使用

%lu(在其基本说明中)。

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

例如,根据C标准,unsigned int在存储大小方面是"大小至少为16位。 "而unsigned long是"至少32位大小。"

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

值12在内存中表示为:

00000000 00001100

如果您使用%u打印将导致12:

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

00000000 00001100 00000000 00000000

,对应于786432的长值

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