【问题标题】:Why doesn't PRIu64 work in this code?为什么 PRIu64 在此代码中不起作用?
【发布时间】:2024-01-09 02:40:02
【问题描述】:

根据this answer,我尝试打印uint64_t,但它给了我一个错误:

错误:在 'PRIu64' 之前需要 ``)'

以下是显示我正在尝试做的最小代码:

#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <cstdio>

class X {
  X() {
    uint64_t foo = 0;
    printf("%07" PRIu64 ": ", foo);
  }
};

int main() {}

这个最小的代码可以编译,但我的实际代码没有。但是,我尝试过将 X::X() 中的 2 行与我的实际代码完全相同,但这不起作用。

我应该寻找什么来进一步调试?我的实际代码还有#includes 其他标题。这会导致问题吗?包含标题的顺序重要吗?

编辑 PRIu64在我的机器上定义如下:

# if __WORDSIZE == 64
#  define __PRI64_PREFIX    "l"
#  define __PRIPTR_PREFIX   "l"
# else
#  define __PRI64_PREFIX    "ll"
#  define __PRIPTR_PREFIX
# endif

# define PRIu64     __PRI64_PREFIX "u"

【问题讨论】:

  • 为什么在 C++ 中使用 printf?此外,我们无法调试我们看不到的代码...常见错误包括缺少;或)。
  • 您能检查一下PRIu64 的确切定义吗?
  • 我知道cout。 :) 它在我的系统上比printf 慢,所以我更喜欢仅在printf 不够好的情况下使用它。我知道你不能调试你看不到的代码。我希望对可能出现的问题有一些想法,以便我可以尝试进一步调试。
  • @Deidara-senpai:添加给您错误的行,因为您的最小示例已编译。
  • @Ajay 已编辑问题。这给了我一些关于如何进一步调试的想法。谢谢。

标签: c++ printf c++03


【解决方案1】:

在 C++ 中,宏不会仅通过包含文件来自动定义。

您需要添加以下内容:

#define __STDC_FORMAT_MACROS 1

之前

#include <inttypes.h>

How to printf uint64_t? Fails with: "spurious trailing ‘%’ in format"

【讨论】:

  • 我想知道你是否真的阅读过这个问题和我的代码。不确定我是否遵循链接到其他答案的意义,我已经在问题的第一行中链接到了该答案,这意味着我在提出问题之前已经阅读了该答案。
【解决方案2】:

我刚刚在自己的代码中发现此问题的另一种可能性是,如果另一个标头已经拉入 &lt;inttypes.h&gt;您定义 __STDC_FORMAT_MACROS 之前。例如:

Utils.h(可能最初是为 C 编写的,就像我们的例子一样):

#include <inttypes.h>

// ... Function declarations

MyFile.cpp

#include "Utils.h"

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

由于inttypes.h已经被Util.h包含,编译器不再包含它,也看不到__STDC_FORMAT_MACROS的声明。

解决方案是编辑Utils.h 以包含#define __STDC_FORMAT_MACROS,或者确保在对MyFile.cpp 进行任何包含之前对其进行定义。

#define __STDC_FORMAT_MACROS
#include "Utils.h"
#include <inttypes.h>

最初的设置实际上在 Ubuntu 上的 GCC 4.8 上编译得很好,但在 PowerPC 的旧 ltib GCC 4.3 工具链上编译失败,这让一开始更加令人困惑。

【讨论】:

    【解决方案3】:

    PRIu64 没有在你使用它的地方定义。

    用字符串"llu" 替换它,您的代码将编译(但这不是修复,它只是说明问题)

    也许include 不见了。也许超过 zealos 包括守卫,并且它被包含在没有魔法令牌块 define 的情况下。也许你的 pch 坏了。

    【讨论】:

    • 我发现没有包含标头,尽管我已经完全按照上面的方式使用了#include 指令。我从inttypes.h 复制了#defines,然后它就可以工作了。什么会导致包含的标头不包含在内? #include 周围没有警戒语句。
    • 0Pch(预编译头文件)。语用语。守卫在头球内。大多数编译器都有办法从哪里转储它们包含的文件。或者您可以将错误填充到标头中并重新编译源文件。
    【解决方案4】:

    如果您使用的是 android JNI 平台。把它放在你的 Android.mk 中:

    LOCAL_CPPFLAGS := -D__STDC_FORMAT_MACROS
    

    【讨论】:

    • 我也在想同样的事情。比在整个代码中#defining 它要好得多。
    最近更新 更多