【问题标题】:Print a size_t in a OS-independent architecture independent way以独立于操作系统的架构独立方式打印 size_t
【发布时间】:2016-10-23 12:37:56
【问题描述】:

假设你有以下sn-p的代码:

include <stdio.h>
size_t nodeID = 5;
printf("nodeID = %lu", nodeID);

这将在 64 位系统上运行而不会引发任何警告,但会在 32 位系统上为 %lu 生成转换警告。

我们可以使用%z modifier处理它

但是,这在使用“I”修饰符的 Visual Studio 上不起作用。

是否有任何可用的方法以独立于架构和独立于操作系统的方式解决这个问题?

【问题讨论】:

  • 如果nodeID 在所有 CPU 环境中都具有相同的大小不是更好吗?您可以声明它uint64_tuint32_t,这样程序就不会改变行为,如果不希望它在 x86 和 x64 上以不同方式运行。
  • 您可以编写自己的 10 格打印方法。
  • "%zu" 格式应该是标准且独立的方式。不幸的是,Visual Studio C 编译器不得不长期跳过以下标准。不过,最后几个版本(2013 和 2015)应该完全兼容 C99。
  • 如果您想编写符合标准的现代 C 代码,解决方案很简单:使用符合标准的现代编译器和库。 MSVC 及其标准库自 17 年以来没有 2 个版本的标准。
  • @Someprogrammerdude: 1) MS 明确表示他们将不支持 C99。 C 功能在 C++ 中也没有。例如,这包括 VLA。 2) C 标准是 C11,现在已经 5 岁了,他们声明(但不保证)他们只想支持 C11。问题是例如VLA 在 C11 中是可选的,尽管委员会强烈致力于向后兼容 - 巧合吗?谁知道...

标签: c


【解决方案1】:

如您所说,您可以使用z 修饰符:

#include <stdio.h>
size_t nodeID = 5;
printf("nodeID = %zu\n", nodeID);

尽管正如您所说的 IIRC,这可能与旧的 MS 编译器存在兼容性问题。您可以通过以下方式解决此问题:

#ifdef _MSC_VER /* Untested MSC detection */
#define PRIuSIZE Iu
#else
#define PRIuSIZE zu
#endif
#define QUOTE(name) #name
#define STR(macro) QUOTE(macro)
#define USIZE_STR STR(PRIuSIZE)

#include <stdio.h>
size_t nodeID = 5;
printf("nodeID = %" USIZE_STR "\n", nodeID);

另一种方式是:

#include <stdio.h>
#include <inttypes.h>
size_t nodeID = 5;
printf("nodeID = %" PRIu64 "\n", (uint64_t) nodeID);

这显然依赖于 size_t 的长度小于或等于 64 位,我相信它总是如此。

【讨论】:

  • "...我相信它总是如此。" - Believe 是一个糟糕的编程顾问。没有上限。没有%zu,就没有完全兼容的方式——这就是引入%zu的原因。
  • 因为size_t 不能大于uintmax_t,您可以强制转换为uintmax_t 并使用PRIuMAX 来获得正确格式的字母。但是,如果您有&lt;inttypes.h&gt; 标头和uintmax_t,则很有可能您也有%zu 可用。类似的 cmets 也适用于 uint64_t
猜你喜欢
  • 1970-01-01
  • 2011-07-31
  • 2013-06-14
  • 1970-01-01
  • 2018-07-13
  • 2012-06-17
  • 2010-12-22
  • 1970-01-01
  • 2012-06-13
相关资源
最近更新 更多