在交叉编译时,让cinttypes在mingw64-w64上正常工作时,我遇到了很大的麻烦。我已经将其简化为在docker中运行的最小示例。
inttypes_test.cpp
#include <cstdio>
#include <cstddef>
#include <cstdint>
#include <cinttypes>
#include <cstdarg>
__attribute__((format(printf, 1, 2))) static void myPrintf(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
int main(int argc, const char** argv)
{
int i32 = 5;
int64_t i64 = 10;
uint64_t u64 = 20;
myPrintf("Testing int: %" PRId32 ", int64 = %" PRId64 ", size_t = %" PRIu64 "\n", i32, i64, u64);
return 0;
}
Dockerfile
FROM ubuntu:18.04
RUN apt-get update -y && \
apt-get install -y g++-mingw-w64-x86-64 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
ADD inttypes_test.cpp /inttypes-test/
RUN cd "/inttypes-test" && \
/usr/bin/x86_64-w64-mingw32-g++ -Wall -Werror -c inttypes_test.cpp
运行结果给出:
inttypes_test.cpp: In function 'int main(int, const char**)':
inttypes_test.cpp:20:100: error: unknown conversion type character 'l' in format [-Werror=format=]
myPrintf("Testing int: %" PRId32 ", int64 = %" PRId64 ", size_t = %" PRIu64 "\n", i32, i64, u64);
^
inttypes_test.cpp:20:100: error: unknown conversion type character 'l' in format [-Werror=format=]
inttypes_test.cpp:20:100: error: too many arguments for format [-Werror=format-extra-args]
因此,我有点假设<cinttypes>
标头的全部要针对这些平台特定的差异。我在做错什么吗?
答案 0 :(得分:1)
inttypes
是一个红色的鲱鱼,您从myPrintf("%lld", 1LL);
得到同样的警告。它会警告您使用ll
,它在程序中由inttypes宏正确提供了。
这是来自较旧版本的MinGW的宿醉,在该版本中,通过MSVCRT重定向了printf格式,该格式未处理%lld
,因此发出警告是适当的。
您可以通过在文件中添加新的顶行来解决该问题(在包含任何标准之前):
#define __USE_MINGW_ANSI_STDIO 1
,然后使用以下属性:
__attribute__((format(__MINGW_PRINTF_FORMAT, 1, 2)))
static void myPrintf(const char* fmt, ...)
这指示mingw-w64使用其自己的符合ISO标准的printf实现,并相应地匹配-Wformat
警告。 Link to documentation
在我的系统(g ++ 8.2.1)上,即使没有第一行,实际上也可以正确使用%lld
等,因此,我怀疑他们可能已将其修复为默认使用ISO stdio而不是MS stdio。也许MS stdio现在知道%lld
。
值得指出一个错误报告,指出__attribute__((format(printf
应该根据使用的stdio自动正确工作,而不必执行此替代方法。