【问题标题】:'%d' expects argument of type 'int', but argument 2 has type 'long unsigned int' [-Wformat=] [duplicate]“%d”需要“int”类型的参数,但参数 2 的类型为“long unsigned int”[-Wformat=] [重复]
【发布时间】:2014-02-03 08:54:37
【问题描述】:

我不断收到编译警告,但我不知道如何解决:

'%d' expects argument of type 'int', but argument 2 has type 'long unsigned int' [

程序运行良好,但我仍然收到编译警告:

/* Sizeof.c--Program to tell byte size of the C variable */
#include <stdio.h>

int main(void) {
    printf("\nA Char is %d bytes", sizeof( char ));
    printf("\nAn int is %d bytes", sizeof( int ));
    printf("\nA short is %d bytes", sizeof( short ));
    printf("\nA long is %d bytes", sizeof( long ));
    printf("\nA long long is %d bytes\n", sizeof( long long ));
    printf("\nAn unsigned Char is %d bytes", sizeof( unsigned char ));
    printf("\nAn unsigned int is %d bytes", sizeof( unsigned int));
    printf("\nAn unsigned short is %d bytes", sizeof( unsigned short ));
    printf("\nAn unsigned long is %d bytes", sizeof( unsigned long ));
    printf("\nAn unsigned long long is %d bytes\n",
            sizeof( unsigned long long ));
    printf("\nfloat is %d bytes", sizeof( float ));
    printf("\nA double is %d bytes\n", sizeof( double ));
    printf("\nA long double is %d bytes\n", sizeof( long double ));

    return 0;

}

【问题讨论】:

  • %ld替换%d

标签: c compilation printf sizeof


【解决方案1】:

我在 Linux 中遇到了同样的问题。相同的程序在 Windows 中运行没有错误(意味着 '%d' 工作没有错误),但对于 linux,我必须将所有 '%d' 替换为 '%lu' 才能运行程序。

【讨论】:

    【解决方案2】:

    编译器警告您,您可能会遭受精度损失。也就是说,您用于打印sizeof%d 的格式说明符不能打印size_t 的全部范围。将%d 更改为%zu,您的警告就会消失。

    【讨论】:

    • 这实际上不仅仅是精度损失,它可能是段错误或堆栈覆盖。在大多数 64 位系统上传递 size_t 会将 8 个字节压入堆栈,而 %d 将仅读取 4 个字节。他的程序没有崩溃只是一个意外;推送的 8 个字节中的底部 4 个字节恰好包含正确的值(在大端系统上可能不是这种情况)并且 printf 之后没有再读取任何字节。
    • 未知转换z.
    【解决方案3】:

    sizeof 返回size_t 格式字符串需要使用%zu 而不是%dsize_t无符号整数 的类型可能会有所不同(取决于平台),并且可能不是到处都是 long unsigned int,这在草案 C99 标准部分 @987654327 中有介绍@sizeof 运算符段落4

    结果的值是实现定义的,其类型(无符号整数类型) 是 size_t,在(和其他标头)中定义。

    另请注意,对printf 使用错误的格式说明符是未定义的行为,这在7.19.6.1 部分中进行了介绍:

    如果转换规范无效,则行为未定义。248) 如果任何参数不是相应转换规范的正确类型,则行为未定义。

    更新

    Visual Studiodoes not support the z format specifier:

    不支持 hh、j、z 和 t 长度前缀。

    在这种情况下,正确的格式说明符是%Iu

    【讨论】:

    • 在 Windows 上的 GCC 4.8.1 中我得到错误:“unknown conversion type character 'z' in format” when printf'ing %zu.
    • @CzarekTomczak 更新了答案,可能相关。
    • 谢谢沙菲克。不幸的是,这些都不是跨平台的。我必须将 size_t 转换为 (unsigned long) 才能使代码在 Linux 和 Windows 上运行。在 Linux 上使用 %Iu(I as Integer)时出现错误“格式‘%u’需要‘unsigned int’类型的参数”。
    • @CzarekTomczak 您最好使用基于操作系统的ifdef 来设置格式说明符变量并改用它。
    • 现在我会坚持使用演员表,因为这只是一些调试信息,并不那么重要。但我会牢记在我的脑海中,在未来如何以正确的方式做到这一点。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2015-02-27
    • 2014-01-02
    • 2021-05-12
    • 2021-06-22
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多