gpt4 book ai didi

c++ - 从哪个版本的 Visual Studio 开始,vsnprintf moSTLy 符合标准?

转载 作者:IT老高 更新时间:2023-10-28 22:41:44 28 4
gpt4 key购买 nike

根据Microsoft's documentation for vsnprintf ,该函数是 C(++) 运行时库的一部分,至少从 Visual Studio 2003 版开始。

int vsnprintf( char *buffer,        // Storage location for output
size_t count, // Maximum number of characters to write
const char *format, // Format specification
va_list argptr ) // Pointer to list of other arguments

我在问:vsnprintf 是哪个版本的 Visual Studio x86 和 x64 的捆绑 C(++) RTL 实现符合 C99 标准 (ISO/IEC 9899:1999),假设

  • #define _CRT_SECURE_NO_WARNINGS#include <stdio.h> 之前执行,这是 Visual Studio RTL 的现代版本所必需的;
  • 如果 count大于零,则 buffer是指向(至少)count 的指针可写字符;
  • 格式不是 NULL并符合 Microsoft's Format Specification syntax适用于特定版本的 RTL;
  • count 的值并且要生成的字符数都足够小以适合类型 int ;

并且我们希望一致性包括(除了标称输入的基本功能之外)这些要求(由标准规范 snprintf 暗示,vsnprintf 引用):

  1. 在上述假设下不会产生未定义的行为(包括调用 Microsoft's invalid parameter handler);
  2. buffer==NULL 时返回要写入的长度(不包括终止空字符)和 count==0 ,从而允许飞行前确定输出的长度;
  3. buffer!=NULL 时,始终使用终止空字符填充输出字符串和 count>0并且返回的结果是非负的,包括由于小的 count 而截断的输出.

注意 comment : 我愿意承认缺少restrict限定符仍然在允许大部分符合标准的情况下。


文档中关于 (3.) 的一致性模棱两可;据我所知,与 Visual Studio Community 2015 捆绑在一起的实现很好,但并非全部都是。

If there is room at the end (that is, if the number of characters to write is less than count), the buffer will be null-terminated.

文档中还有明确暗示 vsnprintf 的措辞。当 buffer==NULL 时 (1.) 和 (2.) 不符合 C99 标准和 count==0 ;但是文档的这些部分似乎是错误的:

if the number of characters to write is greater than count, these functions return -1 indicating that output has been truncated.

If buffer or format is NULL, or if count is less than or equal to zero, these functions invoke the invalid parameter handler


测试代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdarg.h>

int f( char *buffer,
size_t count,
const char *format,
...
)
{
va_list vArgs;
int vRes;
va_start(vArgs, format);
vRes = vsnprintf( buffer, count, format, vArgs);
va_end(vArgs);
return vRes;
}

int main(void)
{
char vBuf[6];
int j, count;
#ifdef _MSC_VER
printf("_MSC_VER = %ld\n",(long)(_MSC_VER));
#else
printf("_MSC_VER is undefined\n");
#endif
printf("f(NULL,0,\"%%d\",777):%3d\n", f(NULL,0,"%d",777));
for(count=0 ;count<=sizeof(vBuf); ++count)
{
for(j=0; j<sizeof(vBuf)-1; ++j)
vBuf[j] = '!';
vBuf[j] = 0;
j = f(vBuf,count,"%d",777);
printf("f(vBuf,%d,\"%%d\",777):%3d vBuf: \"%s\"\n",count,j,vBuf);
}
return 0;
}

在我安装的 Visual Studio Community 2015 下给予

_MSC_VER = 1900
f(NULL,0,"%d",777): 3
f(vBuf,0,"%d",777): 3 vBuf: "!!!!!"
f(vBuf,1,"%d",777): 3 vBuf: ""
f(vBuf,2,"%d",777): 3 vBuf: "7"
f(vBuf,3,"%d",777): 3 vBuf: "77"
f(vBuf,4,"%d",777): 3 vBuf: "777"
f(vBuf,5,"%d",777): 3 vBuf: "777"
f(vBuf,6,"%d",777): 3 vBuf: "777"

并且在 Visual Studio 2008 的某些安装下(我相信 SP1 + PSDK 7.1)

_MSC_VER = 1500
f(NULL,0,"%d",777): 3
f(vBuf,0,"%d",777): -1 vBuf: "!!!!!"
f(vBuf,1,"%d",777): -1 vBuf: "7!!!!"
f(vBuf,2,"%d",777): -1 vBuf: "77!!!"
f(vBuf,3,"%d",777): 3 vBuf: "777!!"
f(vBuf,4,"%d",777): 3 vBuf: "777"
f(vBuf,5,"%d",777): 3 vBuf: "777"
f(vBuf,6,"%d",777): 3 vBuf: "777"

请注意缺少终止空字符,特别是对于 count==3 ,即使输出是正数。

最佳答案

您现在提到的页面给出了答案:

Beginning with the UCRT in Visual Studio 2015 and Windows 10, vsnprintf is no longer identical to _vsnprintf. The vsnprintf function complies with the C99 standard; _vnsprintf is retained for backward compatibility with older Visual Studio code.

而且您的输出与 _vsnprintf 一致:

Both _vsnprintf and _vsnwprintf functions return the number of characters written if the number of characters to write is less than or equal to count; if the number of characters to write is greater than count, these functions return -1 indicating that output has been truncated.

关于c++ - 从哪个版本的 Visual Studio 开始,vsnprintf moSTLy 符合标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34996375/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com