【问题标题】:C printf cross-platform format without warnings [duplicate]C printf跨平台格式没有警告[重复]
【发布时间】:2017-10-04 16:37:44
【问题描述】:

如何编写代码以在没有警告的情况下进行跨平台编译。例如,我在 x64 平台上没有收到警告,但在 ARM (raspberry PI) 上却收到了警告:

警告:格式“%lu”需要“long unsigned int”类型的参数,但参数 5 的类型为“size_t {aka unsigned int}”

不用说我不想禁用警告。

更多示例和场景:

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 上编译。

【问题讨论】:

  • 对所使用的类型使用正确的格式说明符?使用您使用的标准类型特别容易。
  • 阅读文档以找到每种标准类型的正确格式说明符。
  • 贴出引起waring的代码及其参数的类型。
  • 不要在 C++ 中使用 *printf() 并避免整个问题。
  • 你可以使用std::cout 避免这个问题吗?

标签: c++ c format printf cross-platform


【解决方案1】:

对于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。)

【讨论】:

  • 在 Windows 上,这个演员阵容正在缩小。
  • @BaummitAugen 对。添加了讨论。
【解决方案2】:

可以通过使用显式大小的整数而不是本机数据类型来避免这种特殊警告。

#include <cstdint>

int8_t a = 15; //usually an alias for char
uint16_t b = 4980; //usually an alias for unsigned short
uint32_t c = 1234567890; //usually an alias for unsigned int or unsigned long
int64_t d = 908070605040302010ll; //usually an alias for long long

大小整数的技巧是,例如,如果long 在一个平台上是 32 位,但在另一个平台上是 64 位,那么 long 的任何使用都是不可移植的。但int64_t始终为 64 位,否则它在给定平台上根本不存在。

在您的具体情况下,您的代码似乎假定 size_t 将始终为 64 位,但不能保证这一点。所以你应该改用uint64_t,这保证它最终使用的任何底层数据类型都是64位的(并且是无符号的,这是与size_t相关的唯一保证)。

【讨论】:

    猜你喜欢
    • 2017-11-27
    • 1970-01-01
    • 2021-09-06
    • 2012-12-14
    • 2011-05-29
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    相关资源
    最近更新 更多