MinGW的msvcrt替代品?(例如,获得符合标准的 snprintf) [英] msvcrt alternative for MinGW? (e.g. to get conforming snprintf)
问题描述
所以这是一个有趣的...
So here's a fun one...
我们有一些应该独立于平台的 C 库,即使它们是在 linux 上开发的,因为它们只依赖于 ISO/IEC 9899:1999 中定义的 c 标准库.当我们用 MinGW 编译这些库时,一开始似乎一切正常,但今天我们发现 msvcrt 的 snprintf() 实现是脑残……抱歉,我的意思是不兼容" 与 C99 标准中的定义.
we have a few C libraries which should be platform independent, even though they were developed on linux, because they only rely on the c standard library as defined in ISO/IEC 9899:1999. When we compiled those libraries with MinGW everything seemed to work fine at first, but today we found out that the snprintf() implementation of msvcrt is braindea... sorry, i meant "incompatible" with the definition in the C99 standard.
我原以为 MinGW 会发出警告,告诉我 -std=c99 实际上并不完全受支持.因为否则,我怎么知道?
I would have expected a warning from MinGW, telling me that -std=c99 actually isn't fully supported. Because otherwise, how am i supposed to know?
是否有任何适用于 Windows 的替代 c 标准库,最重要的是:是否可以告诉 MinGW 以某种方式链接它而不是 msvcrt?
Is there any alternative c standard library for windows, and most importantly: can MinGW somehow be told to link against it instead of msvcrt?
如果没有,我们至少需要一个列表或其他可以检查与 msvcrt 和 c99 相关的潜在可移植性问题的东西.
If not, we would at the very least need a list or something where we can check for other potential portability problems concerning msvcrt and c99.
附注:我知道 Cygwin 和 MSYS2,但我更喜欢本机 Windows 二进制文件(部分原因是我们也在 Matlab 中使用我们的库).
PS: I know about Cygwin and MSYS2, but i'd rather have native windows binaries (in part because we also use our libraries in Matlab).
抱歉,我应该更清楚地解释我的 msvcrt 的 snprintf() 问题到底是什么.根据标准,如果输出不适合,则需要 snprintf() 输出 '\0' 作为最后一个字符.但是, msvcrt 不会这样做,因此生成的字符串不再正确终止.我不知道为什么有人会选择以这种方式实现 snprintf(),因为对我来说,省略 '\0' 根本没有任何意义.
Sorry, i should have explained more clearly what exactly my problem with msvcrt's snprintf() is. According to the standard, snprintf() is required to output a '\0' as the last character, if the output doesn't fit. However, msvcrt just doesn't do that, so the resulting string is no longer properly terminated. I have no idea why anyone would choose to implement snprintf() that way, because to me just omitting the '\0' doesn't make any sense at all.
我们也尝试了建议的 __USE_MINGW_ANSI_STDIO,但我想这只是修复了丢失的格式说明符?至少它似乎对我们的具体问题没有影响.
We have also tried the suggested __USE_MINGW_ANSI_STDIO, but i guess that just fixes the missing format specifiers? At least it didn't seem to make a difference for our specific problem.
推荐答案
标准强制 snprintf
的行为如下:
The standard enforces snprintf
to behave like this:
否则,超出第 n-1 个的输出字符是丢弃而不是写入数组,并在实际写入数组的字符末尾写入空字符.
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 版本:
snprintf() 总是空终止吗?
snprintf
in msvcrt is indeed not the standard one, but a Microsoft version as explained here:
Is snprintf() ALWAYS null terminating?
以下代码给出了不合规的结果:
The following code gives non-compliant results:
#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
包含的之前添加:
I get output 41 42 43
which is not standard compliant. To get standard C, you have to add this before the stdio.h
include:
#define __USE_MINGW_ANSI_STDIO 1
现在你得到了符合要求的 41 42 00
.
And now you get 41 42 00
which is compliant.
所有这些程序安全问题的根源在于微软,过去 20 年来,他们一直在其产品中使用不合规的 C 库.
The root of all these program security problems is Microsoft, who have been using non-compliant C libs in their products for the past 20 years.
这篇关于MinGW的msvcrt替代品?(例如,获得符合标准的 snprintf)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!