C printf跨平台格式没有警告 [英] C printf cross-platform format without warnings

查看:390
本文介绍了C printf跨平台格式没有警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你如何编写代码来编译跨平台而不需要警告。例如,我不会在x64平台上收到警告,但我会在ARM(树莓派)上做:

warning:format'%lu'expect the argument of type' long unsigned int',但是参数5的类型是'size_t {aka unsigned int}

不用说我不想禁用警告。
$ b

更多示例和场景:

 警告:format'%lu'需要参数类型' long unsigned int',
,但是参数5的类型是'uint64_t {aka long long unsigned int}'

uint64_t创建; // 8字节
time_t now = time(NULL);
当前时间:%li sec,%lu nanosecs,现在,msg.Created

size_t可能是最高的罪犯:

sizeof的基本使用:

  warning:格式'%lu'需要类型为'long unsigned int',
的参数,但参数4的类型为'unsigned int'
tr_debug(pbJobs size:%lu,sizeof(pbJobs) );

tr_debug相当于Mbed OS平台的printf。是的,我在Mbed操作系统和Linux上编译。

size_t ,假设你有一个足够现代的C库,使用%zu

如果你不能使用 z 修饰符(一些较旧的库不幸地不支持它),在打印时将其转换为足够宽的已知类型,然后使用适合该类型的宽度说明符:

  size_t sz = sizeof(whatever); 
...
printf(%lu,(unsigned long)sz);

只要 超过40亿左右,即可以容纳32位。如果你在一个系统上,其中 size_t 是64位,但是 long 是32,你理论上已经得到了这个问题大小 size_t 可以容纳,但%lu 不能打印。这对你来说是一个问题,如果是这样,怎么办,取决于你。 (理想的解决方案是,如果你的程序库支持它,则返回到%zu ,这是首选解决方案,并且在32位,64位或者我猜你可以使用 unsigned long long %llu 。) / p>

How do you write code to compile cross-platform without warnings. For example, I don't get warnings on x64 platform, but I do on ARM (raspberry PI):

warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘size_t {aka unsigned int}

Needless to say I don't want to disable warnings.

More examples and scenarios:

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 is probably the highest offender:

Basic use of 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 is equivalent of printf for Mbed OS platform. Yes, I compile on Mbed OS and Linux.

解决方案

For size_t, assuming you have a sufficiently modern C library, use %zu.

If you can't use the z modifier (some older libraries unfortunately don't support it), cast to a wide-enough known type when printing, and then use a width specifier appropriate to that type:

size_t sz = sizeof(whatever);
...
printf("%lu", (unsigned long)sz);

This works as long as you're never working with a size larger than 4 billion or so, i.e. that can fit in 32 bits. If you're on a system where size_t is 64 bits but long is 32, you've theoretically got the problem of a size which size_t can hold but %lu can't print. Whether this is a problem for you, and what to do if it is, is up to you. (The ideal solution, if your library supports it, is to go back to %zu, which is the preferred solution and doesn't have this problem in 32-bit, 64-bit, or any other sized environments. Or I guess you could use unsigned long long and %llu.)

这篇关于C printf跨平台格式没有警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆