【问题标题】:format %lu expects argument of type 'long unsigned int' but argument 3 has type long long unsigned int, cast from printer to integer of different size格式 %lu 需要“long unsigned int”类型的参数,但参数 3 的类型为 long long unsigned int,从打印机转换为不同大小的整数
【发布时间】:2021-01-11 15:41:30
【问题描述】:

我在编译代码时收到警告。这些警告包括:format %lu expects argument of type 'long unsigned int' but argument 3 has type long long unsigned int & cast 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 在所有符合标准的平台上都是 1,所以 sizeof(a)-1 == 0。 C99 6.5.3.4 sizeof 运算符 - 3:当应用于具有 char、unsigned char 或 signed char 类型(或其限定版本)的操作数时,结果为 1....

标签: c printf stdio integer-promotion


【解决方案1】:

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), (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), (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 问题。

【讨论】:

  • 我尝试将 %lu 更改为 %llu & %zu,但同样的错误不断返回。是的,我使用的是 WIN64。我只是不知道要在该打印语句中更改什么来修复错误。
  • 对于本节:(long)&a + sizeof(a)-1),我只是将 &a 用括号括起来 +sizeof(a)-1) 以获得 (long) (&a + sizeof (a)-1)。由于某种原因,这解决了“%lu 错误,我不知道为什么或如何,但“从打印机转换为不同大小的整数”错误仍然存​​在。
  • @azwahd180 - 您还在将地址投射到(long) 吗?如果是这样,那就是在 WIN64 ABI 上将 64 位地址截断为 32 位值。此外,您应该转换为 unsigned 类型。例如(unsigned long long)(uintptr_t)(long) 已签名 - 格式说明符需要无符号类型/表达式。
  • 我将转换地址更改为 '(unsigned long long)' 和 '(uintptr_t)' 但我不断收到相同的错误以及一个新的错误,指出参数太多。我现在有'printf("%lu - %lu",(long)&a, (long)(&a + sizeof(a)-1))。还将 %lu 更改为 %llu。
  • 我的意思是 - 您正在将 (long)(一个 signed 长)传递给格式说明符 %lu,它需要一个 (unsigned long)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-03
  • 1970-01-01
  • 2014-01-28
  • 2016-12-20
  • 2014-01-02
  • 1970-01-01
相关资源
最近更新 更多