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 库。
这是一个有趣的...
我们有一些 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
表现如下:
msvcrt 中的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.
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 库。