【问题标题】:Warning C4477 in Visual Studio 2015Visual Studio 2015 中的警告 C4477
【发布时间】:2015-12-30 18:12:46
【问题描述】:

当我编译以下代码时,Visual Studio 显示 C4477 警告。为什么 Visual Studio 会生成此警告?以及如何修复此代码?

警告:警告 C4477:“printf”:格式字符串“%d”需要“int”类型的参数,但可变参数 1 的类型为“int *”

#include <stdio.h>

int main(void) {
    int num = 0;
    int *pi = &num;

    printf("Address of num: %d Value: %d\n", &num, num);
    printf("Address of pi: %d Value: %d\n", &pi, pi);

    return 0x0;
}

【问题讨论】:

  • %d 需要一个 int 参数。要打印指针,请使用%p。请阅读printf 的手册页或搜索“printf 格式字符串”!

标签: c visual-studio-2012 warnings


【解决方案1】:

因为您使用了不正确的格式说明符。 %d 是打印一个int。要打印指针,请使用%p 并转换为void*

printf("Address of num: %p Value: %d\n", (void*)&num, num);
printf("Address of pi: %p Value: %p\n", (void*)&pi, (void*)pi);

需要转换为void*,因为可变参数函数不会按照%p 的要求进行从type *void * 的任何类型转换。引用标准:

7.21.6 格式化输入/输出函数(C11 草案)

p 参数应该是一个指向 void 的指针。指针的值为 转换为一系列打印字符,在 实现定义的方式。

【讨论】:

    【解决方案2】:

    换一种说法,你的参数 &num(或以 (void *) &num 的形式)告诉编译器你希望将 num 的地址传递给函数,而不是 num 的值。带有 %d 格式说明符的 printf 函数应该是一个值,而不是地址。抱怨是编译器意识到了这种差异。

    注意:在 32 位工作中,地址和 int 都是 32 位,所以事情(即 %d)可以正常工作。但是,在 64 位世界中,int 仍然是 32 位长,但地址是 64 位。 IE。你不能用 %d 准确地表示指针的值。这就是创建 %p 的原因。它(编译器)足够聪明,可以在编译为 32 位时将 %p 参数处理为 32 位数量,在编译为 64 位时处理为 64 位数量。

    阅读计算机架构、硬件堆栈及其位大小。在此过程中,您可能还希望了解小端和大端之间的区别。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      • 2016-12-30
      • 2016-04-28
      • 2017-07-27
      • 1970-01-01
      • 2011-02-10
      • 2016-03-02
      相关资源
      最近更新 更多