c - gcc std=gnu90 的 size_t 格式警告

标签 c string-formatting gcc-warning size-t

我目前正在使用 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/

相关文章:

java - Log4j 隐式字符串格式化

c++ - 如何使用参数集合格式化 std::string?

google-apps-script - 谷歌应用程序脚本 : How to copy text and preserve formatting?

c - "assignment makes integer from pointer without a cast"在 c

c - 为什么 -Wcast-align 不警告在 x86 上从 char* 到 int* 的转换?

c++ - 基于OpenCV的背景提取

C - strcmp() 数组中的两个字符串

c - 通过传递指针的地址来初始化本地指针

检查输入是否是C中的txt文件

c++ - 是否存在检测有符号类型的位移位操作的 GCC 警告?