MinGW的msvcrt替代品?(例如,获得符合标准的 snprintf) [英] msvcrt alternative for MinGW? (e.g. to get conforming snprintf)

查看:151
本文介绍了MinGW的msvcrt替代品?(例如,获得符合标准的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆