c - 有没有更好的方法来缓解这个警告?
问题描述
我有一个结构,我使用位域来优化内存。我有一个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));
}
解决方案
虽然您绝对应该在其他答案中应用修复以获得可移植格式说明符,但警告将持续存在。原因是可变参数函数的额外参数(如printf
进行参数提升)。参数提升包括整数提升。
整数提升的规则会将转换等级小于int
/的任何整数unsigned
以及位字段转换为int
/ unsigned
。因此,对于您的初始位域,您会int
自动获得。
对于转换等级高于int
/的整数unsigned
,不会发生提升。因此,您的位域不会提升为uint64_t
,并且您会收到有关参数不匹配的警告。你需要一个演员表。
(uint64_t)self->mid
size_t
顺便说一句,由于没有人提到, a (运算符的类型)的可移植格式说明sizeof
符是%zu
. 您应该使用它而不是%ld
.
推荐阅读
- android - Horizontal ScrollView 移除 textView 除非处于纵向模式
- cypress - 有没有办法 2 在 cypress 中创建多个命令文件
- java - 如何手动排序 Swagger UI 上显示的端点?
- javascript - 如何使用 JavaScript 和 jQuery 动态添加文本?
- node.js - 我放入哈巴狗模板的 json 数据将 '<' 放在字符串的开头,将 '>' 放在结尾。为什么?我该如何摆脱它?
- python - 在不重新索引或丢失索引的情况下在列上连接不同形状的数据框
- laravel - 更新和销毁方法在 laravel eloquent 模型中不起作用?
- react-native - React Native - 用滚动动画底部标签栏
- java - Android Webview EvaluateJavascript 有时不返回响应
- google-apps-script - 除非已安装的触发器已经存在,否则如何创建“创建触发器”附加菜单选项?