MinGW 的 msvcrt 替代品? (例如,获得符合要求的 snprintf)

msvcrt alternative for MinGW? (e.g. to get conforming snprintf)

这是一个有趣的...

我们有一些 C 库 应该 是平台独立的,即使它们是在 linux 上开发的,因为它们只依赖于定义的 c 标准库在 ISO/IEC 9899:1999 中。当我们用 MinGW 编译这些库时,一开始一切似乎都运行良好,但今天我们发现 msvcrt 的 snprintf() 实现是 braindea...抱歉,我的意思是“不兼容" 与C99标准中的定义。

我原以为 MinGW 会发出警告,告诉我 -std=c99 实际上并未得到完全支持。因为否则,我怎么知道?

windows 是否有任何替代的 c 标准库,最重要的是:能否以某种方式告诉 MinGW link 而不是 msvcrt?

如果没有,我们至少需要一个列表或其他可以检查有关 msvcrt 和 c99 的其他潜在可移植性问题的东西。

PS: 我知道 Cygwin 和 MSYS2,但我宁愿拥有原生 windows 二进制文件(部分原因是我们也在 Matlab 中使用我们的库)。

编辑: 抱歉,我应该更清楚地解释我的 msvcrt 的 snprintf() 问题到底是什么。根据标准,如果输出不合适,则 snprintf() 需要输出 '\0' 作为最后一个字符。但是,msvcrt 只是不这样做,因此生成的字符串不再正确终止。我不知道为什么有人会选择以这种方式实现 snprintf() ,因为对我来说只是省略 '\0' 根本没有任何意义。

我们也尝试了建议的 __USE_MINGW_ANSI_STDIO,但我想这只是修复了缺少的格式说明符?至少它似乎对我们的具体问题没有影响。

如果您需要来自 MinGW-w64 的 C99 stdio,您可以定义 __USE_MINGW_ANSI_STDIO 以便绕过 msvcrt 实现。最好通过编译器参数来定义它

-D__USE_MINGW_ANSI_STDIO

或者,您可以尝试将设置为 link 的 MinGW-w64 版本与新的 ucrt 一起使用,但我不知道任何预先存在的易于使用的稳定版本就是这样设置的。

标准强制 snprintf 表现如下:

Otherwise, output characters beyond the n-1st are discarded rather than being written to the array, and a null character is written at the end of the characters actually written into the array.

msvcrt 中的

snprintf 确实不是标准版本,而是 Microsoft 版本,如下所述:
Is snprintf() ALWAYS null terminating?

以下代码给出了不合规的结果:

#include <stdio.h>

int main (void)
{
  char dst[3];
  snprintf(dst, 3, "%c%c%c", 'A', 'B', 'C');

  for(size_t i=0; i<3; i++)
  {
    printf("%.2X ", dst[i]);
  }
}

我得到不符合标准的输出 41 42 43。要获得标准 C,您必须在 之前添加此 stdio.h 包括:

#define __USE_MINGW_ANSI_STDIO 1

现在你得到 41 42 00 是合规的。

所有这些程序安全问题的根源是微软,他们在过去 20 年中一直在其产品中使用不合规的 C 库。