c++ - Mingw64-w64 属性(格式)和 <cinttypes> header

标签 c++ ubuntu gcc cross-compiling mingw-w64

交叉编译时,我在让 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> 的全部要点header 的目的是掩盖这些特定于平台的差异。我做错了什么吗?

最佳答案

inttypes 是一个转移注意力的话题,您会从 myPrintf("%lld", 1LL); 得到相同的警告。它警告有关 ll 的使用,它在您的程序中是(正确)由 inttypes 宏传递的。

这是旧版本 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 警告。 Link to documentation


在我的系统(g++ 8.2.1)上,即使没有第一行,使用 %lld 等实际上也能正确运行,所以我怀疑他们可能已经修复它以使用 ISO stdio 而不是 MS默认为 stdio。或者也许 MS stdio 现在知道 %lld

可能值得在错误报告中指出 __attribute__((format(printf) 应该根据正在使用的 stdio 自动正常工作,而无需执行此解决方法。

关于c++ - Mingw64-w64 属性(格式)和 <cinttypes> header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54265217/

相关文章:

c++ - macOS High Sierra 系统日志不工作

c++ 抽象基类私有(private)成员

c# - 在没有任务栏按钮的情况下从 C++ 启动 C# 应用程序

php - 使用 apt-src 在 ubuntu 上编译 php 时遇到问题

c - 为什么我的程序在 GCC 下不进入处理程序模式?

c++ - 从gdb中模板类的成员函数打印静态变量

c++ - 如何分离 `QObject` 的父子关系的关注点,例如与其他所有者互操作?

ubuntu - 用于 vim/tmux 的 headless SSH 服务器上的 xsel/xclip

node.js - 在 Ubuntu 14.04 上按照最新的 nodejs 安装步骤有什么问题?

c++ - Switch case 语句如何在内部实现或工作?