格式%lu期望参数为'long unsigned int'类型,但参数3为long long unsigned int类型,从打印机转换为不同大小的整数

问题描述

我在编译代码时收到警告。这些警告包括:format %lu expects argument of type 'long unsigned int' but argument 3 has type long long unsigned intcast from printer to integer of different size

我似乎不知道怎么了。任何有关如何解决此问题的建议都将受到赞赏。

void printBits(size_t const size,void const * const ptr);


int main()
{

// variables are not in order on purpose for the first step in running the code.

float c;
char a;
double d;
int b;

d = 561232019;       /* 8 bytes */
c = 154.6;           /* 4 bytes */
b = -83273;          /* 4 bytes */
a = 42;              /* 1 byte */




printf("\n--------------------------------------------\n");

printf("LABEL  -  ADDRESS(hex)    ADDRESS (dec) [S - E]  -  BINARY\n"); 
printf("A -      ");
printf("%p  -   ",&a);
printf("%lu -  %lu         ",(long)&a,(long)&a + sizeof(a)-1); // the two errors occur at      
//this line as well as the other identical print statements for each variable used. This print 
//statement is identical to when using b,c,d and all have the same warnings. I just used this part 
//of code to find out how to fix this error so I could fix all the other identical print statements. 

printf("%d -        ",a);
printBits(sizeof(a),&a);
printf("\n--------------------------------------------\n");

解决方法

带有sizeof(a)的表达式可能会将结果提升为size_t的表达式-在该平台上,这显然是一个无符号的64位类型。我怀疑您使用的是Windows(WIN64),其中long是32位。请参阅:LLP64。因此,您将需要%llu

请注意,您还可以将%zu用于size_t参数。将地址截断到32位%lu也可能是错误的。您正在使用64位指针。使用%p。仔细阅读C stdio *printf spec可能会有用。


@Antii的评论也值得考虑:您可以安全地将地址投射到uintptr_t(反过来并不是那么简单),并利用<inttypes.h> PRIxPTR格式限定符。从理论上讲,这是一个可选类型,但将存在于任何规范平台上。


以下是一些示例:(我希望它们是正确的-我假设使用64位指针,但仅对其进行了简要测试)

#include <inttypes.h>
#include <stdio.h>

int main (void)
{
    char a = 42;

    // asserts: sizeof(unsigned long long) >= sizeof(char *)
    // 64-bit unsigned values and 64-bit hexadecimal values:

    printf("%llu - %llu\n",(unsigned long long) (& a),(unsigned long long) (& a + sizeof(a) - 1));
    printf("%llx - %llx\n",(unsigned long long) (& a + sizeof(a) - 1));
    printf("\n");

    // use of `uintptr_t` and C string macro concatenation:
    // hexadecimal uintptr_t values with and without leading zeroes.

    const char *fmt = "%" PRIxPTR " - %" PRIxPTR "\n";
    printf(fmt,(uintptr_t) (& a),(uintptr_t) (& a + sizeof(a) - 1));

    printf("0x%016" PRIxPTR " - 0x%016" PRIxPTR "\n",(uintptr_t) (& a + sizeof(a) - 1));
    printf("\n");

    // finally the most 'elegant' solution: (unpadded) hexadecimal values:

    printf("%p - %p\n",& a,& a + sizeof(a) - 1);

    return (0);
}

注释:@KamilCuk提出了一个重要观点:从技术上说%p仅为(void *)自变量定义。除了古老的/异国情调的平台外,这在其他任何地方都不太可能成为问题-但这是规范的一部分。请参阅this问题。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...