我目前正在使用 C 语言开发一个软件项目,该项目必须在各种平台上运行。我尽量保持接近 C90 标准,但需要一些普遍支持的扩展,如 stdint.h 和 unsigned long long 类型。我故意不想“回退”到 C99 标准,因为我使用的一些编译器不支持所有 C99 功能,如混合声明和代码等。
因此,我目前使用 gcc 在我的(64 位 Ubuntu)开发机器上用 -Wall -Wextra -pedantic -std=gnu90
(不是 C90,因为我使用 unsigned long long 等)来解决所有不符合格式的代码部分。到目前为止,我可以调整我的代码以消除除一个之外的所有警告:我无法为 size_t 找到不会产生来自 gcc 的警告的正确 (printf) 格式。考虑以下示例代码,它说明了我尝试过的大部分内容:
#include <stdint.h>
#include <stdio.h>
int main()
{
printf("%zu", sizeof(int)); /* C99 format specifier for size_t */
printf("%u", sizeof(int)); /* Treat size_t as unsigned int */
printf("%lu", sizeof(int)); /* Treat size_t as unsigned long int (only works when size_t is "typedef"ed to unsigned long int) */
return 0;
}
当使用 -Wall -Wextra -pedantic -std=gnu90
编译时,我收到前两行的警告:
test.c:6:3: warning: ISO C90 does not support the ‘z’ gnu_printf length modifier [-Wformat=] test.c:7:3: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
虽然我没有收到第三行的警告,但这只是我的开发系统的情况。在其他系统上,特别是在 size_t 是某种“自定义”类型或未“typedef”为 unsigned long long 的系统上,仍然会出现警告。
我很清楚在 C90 中没有 size_t 的格式说明符,但在 C99 中有一个。但是,我认为设置 -std=gnu90
会给我“z”格式说明符,但事实证明这个假设是不正确的。
因为我无法摆脱警告,我尝试用一些预处理器定义来定义格式说明符,如下所示:
#include <inttypes.h>
#include <stdio.h>
#ifdef __GNUC__
#define GLUE(x, y, z) x##y##z
#define GLUE_FORMAT(prefix, size) GLUE(PRI, prefix, size)
#define UINT_FORMAT(size) GLUE_FORMAT(u, size)
#define SIZE_T_FORMAT UINT_FORMAT(__SIZEOF_SIZE_T__)
#else /* C99 fall-back */
#define SIZE_T_FORMAT "zu"
#endif
int main()
{
printf("%" SIZE_T_FORMAT, sizeof(int));
return 0;
}
我认为这应该给我正确的格式说明符,唯一的限制是 size_t 是无符号的(到目前为止,它在我的所有目标平台上都是如此)。但是,这也不起作用:
test.c:15:3: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
在给定约束的情况下,是否有任何方法可以克服此警告(或找到更优雅的解决方案而不求助于 -std=c99
)?
最佳答案
你会考虑 Actor 吗?转换通常是问题的标志,但在某些时候,只写可能是最简单的
printf("%u", (unsigned) sizeof(int));
你甚至可以将转换组合成一个宏
#define usizeof(a) ((unsigned)sizeof(a))
printf("%u", usizeof(int));
这将使它足够容易使用。
关于c - gcc std=gnu90 的 size_t 格式警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29432392/