Mingw64-w64 属性(格式)和<cinttypes>标题
Mingw64-w64 attribute(format) and <cinttypes> header
交叉编译时,我在让 cinttypes 在 mingw64-w64 上正常工作时遇到了严重的问题。我已经把它归结为一个在 docker 中运行的最小(ish)示例。
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>
标题的全部意义在于掩盖这些特定于平台的差异。我做错了什么吗?
inttypes
是红鲱鱼,您会从myPrintf("%lld", 1LL);
那里得到相同的警告。它警告使用ll
,在您的程序中,它是由 inttype 宏(正确)传递的。
这是旧版本的 MinGW 的宿醉,其中 printf 格式是通过不处理%lld
的 MSVCRT 重定向的,因此警告是合适的。
您可以通过向文件添加新的顶行来解决此问题(在任何标准包含之前):
#define __USE_MINGW_ANSI_STDIO 1
然后使用以下属性:
__attribute__((format(__MINGW_PRINTF_FORMAT, 1, 2)))
static void myPrintf(const char* fmt, ...)
这指示 mingw-w64 使用符合 ISO 标准的自己的 printf 实现,并相应地匹配-Wformat
警告。 文档链接
在我的系统(g++ 8.2.1)上,即使没有第一行,使用%lld
等实际上也可以正确运行,所以我怀疑他们可能已经将其修复为默认使用 ISO stdio 而不是 MS stdio。或者也许 MS stdio 现在知道%lld
.
可能值得一个错误报告来指出__attribute__((format(printf
应该根据正在使用的stdio自动正常工作,而无需执行此解决方法。
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中