这个问题在这里已有答案:
如何在没有警告的情况下编写代码来编译跨平台 . 例如,我没有在x64平台上收到警告,但我在ARM(raspberry PI)上收到警告:
警告:格式'%lu'需要'long unsigned int'类型的参数,但参数5的类型为'size_t
不用说我不想禁用警告 .
更多示例和场景:
warning: format ‘%lu’ expects argument of type ‘long unsigned int’,
but argument 5 has type ‘uint64_t {aka long long unsigned int}’
uint64_t Created; // 8 bytes
time_t now = time(NULL);
"Current time: %li sec, %lu nanosecs", now, msg.Created
size_t可能是最高的罪犯:
sizeof的基本用法:
warning: format ‘%lu’ expects argument of type ‘long unsigned int’,
but argument 4 has type ‘unsigned int’
tr_debug("pbJobs size: %lu", sizeof(pbJobs));
tr_debug相当于Mbed OS平台的printf . 是的,我在Mbed OS和Linux上编译 .
2 回答
对于
size_t
,假设您有一个足够现代的C库,请使用%zu
.如果你不能使用
z
修饰符(遗憾的是一些较旧的库不支持它),在打印时强制转换为足够广泛的已知类型,然后使用适合该类型的宽度说明符:只要你在
size_t
是64位但是long
是32的系统上这是有效的,你理论上会遇到size_t
可以容纳但%lu
无法打印的大小的问题 . 这对您来说是否是一个问题,以及如果它是该怎么做,取决于您 . (理想的解决方案,如果你的库支持它,是回到%zu
,这是首选的解决方案,在32位,64位或任何其他大小的环境中没有这个问题 . 或者我想你可以使用unsigned long long
和%llu
. )通过使用显式大小的整数而不是本机数据类型,可以避免此特定警告 .
具有大小整数的技巧是,例如,如果
long
在一个平台上是32位,而在另一个平台上是64位,则long
的任何使用都是不可移植的 . 但int64_t
将 always 为64位,否则它根本不会存在于给定平台上 .在具体情况下,您的代码似乎假设
size_t
将始终为64位,但不能保证这一点 . 所以你应该使用uint64_t
,这保证了它最终使用的基础数据类型,它将是64位(和无符号,这是与size_t
相关的唯一保证) .