1

如果添加了第 4 行中的 include 语句(未注释),则以下程序会导致编译器警告。

编译器:gcc 8.1.0 版(i686-win32-dwarf-rev0,由 MinGW-W64 项目构建)

#define __STDC_FORMAT_MACROS

// Adding this and -Wall results in compiler warning
//#include "stdio.h"

#include <cstdint>
#include <cinttypes>
#include <cstdio>

int main()
{
    int64_t i     = 0;
    printf("%" PRId64, i);
}

警告是:

testlld.cpp:11:14: warning: unknown conversion type character 'l' in format [-Wformat=]
  std::printf("%" PRId64, i);
              ^
testlld.cpp:11:14: warning: too many arguments for format [-Wformat-extra-args]
testlld.cpp:11:14: warning: unknown conversion type character 'l' in format [-Wformat=]
testlld.cpp:11:14: warning: too many arguments for format [-Wformat-extra-args]

有人可以解释会发生什么吗?

我当然可以只使用 <cstdio> 来解决这个问题,这在这种情况下是正确的。

但这又引出了另一个问题……

假设我有一个包含在两个实现文件中的头文件——一个用 C 编译器编译,一个用 C++ 编译器编译。头文件需要使用“stdio.h”,因为它需要使用 C 编译器进行编译。这是否意味着包括该头文件在内的所有代码也必须使用“stdio.h”而不是 <cstdio>,即使它是 C++ 代码?

4

2 回答 2

1

按照上面的建议,我做了以下事情,编译时没有警告。

// Needed to define the macros for data types in inttypes.h
#define __STDC_FORMAT_MACROS

// This part in header file (.h) re-used by this file as well as .c files compiled with C compiler
#ifdef __cplusplus
#include <cstdio>
#else
#include "stdio.h"
#endif

#include <cstdint>
#include <cinttypes>
#include <cstdio>

int main()
{
    int64_t i     = 0;
    printf("%" PRId64, i);
}

对我来说,这看起来是一个很好的(正确的?)解决方案。

于 2021-09-16T08:49:08.053 回答
1

这似乎是一个已知的错误:https ://gcc.gnu.org/bugzilla/show_bug.cgi?id=60434

这是有道理的,因为 - 尽管有警告 - 64 位整数被正确打印。

顺便说一句,当编译为C(将包含的标头更改为.h)时,由定义的格式字符串PRId64I64d。在编译为 C 或 C++ 时,使用此格式字符串不会发出警告。因此,一种可能的解决方法是使用

    printf("%I64d", i);

另一种选择是使用-D__USE_MINGW_ANSI_STDIO.

于 2021-09-16T08:18:48.850 回答