首页 > 解决方案 > 有没有更好的方法来缓解这个警告?

问题描述

我有一个结构,我使用位域来优化内存。我有一个uint64_t类型,我想打印它的值。编译时它向我显示此警告:format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘long unsigned int:48’ [-Wformat=]

我已经尝试通过在编译时键入来抑制此警告-Wno-format。我想知道是否有更好的方法来做到这一点。

这里有一些代码:

#include <stdint.h>
#include <stdio.h>

typedef struct gn_addr 
{
    unsigned int m:1;
    unsigned int st:5;
    unsigned int reserved:10;
    uint64_t mid:48;
} gn_addr ;

void gn_addr__print(gn_addr *self)                                                                                                                                                                         
{                                                                                                                                                                                                          
    printf("M=>%d\nST=>%d\nReserved=>%d\nMID=>%lu\nTotal size %ld bytes\n",                                                                                                                                
         self->m, self->st, self->reserved, self->mid, sizeof(self));                                                                                                                                   
} 

标签: cprintfwarningsbit-fieldsgcc-warning

解决方案


虽然您绝对应该在其他答案中应用修复以获得可移植格式说明符,但警告将持续存在。原因是可变参数函数的额外参数(如printf进行参数提升)。参数提升包括整数提升。

整数提升的规则会将转换等级小于int/的任何整数unsigned以及位字段转换为int/ unsigned。因此,对于您的初始位域,您会int自动获得。

对于转换等级高于int/的整数unsigned,不会发生提升。因此,您的位域不会提升为uint64_t,并且您会收到有关参数不匹配的警告。你需要一个演员表。

(uint64_t)self->mid

size_t顺便说一句,由于没有人提到, a (运算符的类型)的可移植格式说明sizeof符是%zu. 您应该使用它而不是%ld.


推荐阅读