【发布时间】:2016-01-20 22:48:52
【问题描述】:
我正在使用我的前任使用的 C 代码库:
#ifdef _MSC_VER
// Map to equivalent function
#define snprintf sprintf_s
#endif
代码库需要在 Linux (gcc/clang)、OSX (gcc/clang) 和 Windows (VS) 上编译。我第一次尝试在 Visual Studio 2015 中编译代码。以前使用过 Visual Studio 2010。我遇到了here 描述的错误,并且能够使用已接受答案中的线索进行编译:
#ifdef _MSC_VER
#if _MSC_VER<1900
#define snprintf sprintf_s
#endif
#endif
该项目现在可以使用 Visual Studio 2015 编译并在 OSX 上运行。但是,我担心sprintf_s 文档中的一个声明:
与 snprintf 不同,sprintf_s 保证缓冲区将以空值结尾(除非缓冲区大小为零)。
如果 Visual Studio 包含符合 C99 的 snprintf 版本,是否不应该保证缓冲区以空值终止?
我写了一个小程序来评估行为。
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
char buf[5];
snprintf(buf, sizeof(buf), "abcdef");
printf("buffer: %s\n", buf);
printf("size of buffer: %lu\n", strlen(buf));
printf("last character a null terminator?: %s\n",
(strcmp(&buf[4], "\0") == 0) ? "yes" : "no");
return 0;
}
我在 OSX 和 Windows 上使用 Visual Studio 2015 构建并运行了该程序。
在 OSX 上,输出为:
~$c99 main.c
~$./a.out
buffer: abcd
size of buffer: 4
last character a null terminator?: yes
在带有 Visual Studio 2015 的 Windows 7 上,输出为
> printf_evaluation.exe
buffer: abcd
size of buffer: 4
last character a null terminator?: yes
这不是表明输出实际上是空终止的,并表明 MSDN 文档不正确吗?我的例子是不是太琐碎了?是否存在 snprintf 的输出可能不会在 Visual Studio 2015 中以 NULL 终止的情况?
【问题讨论】:
-
我认为,他们的意思是 与 _snprintf 不同,它确实不会以空值终止。 VS 根本不知道 snprintf(除了作为 sprintf_s 的宏)
-
我怀疑这是一个文档错误,而不是在 Visual Studio 中实现
snprintf()的任何异常/错误。 -
微软 1980 年代实现的
snprintf与 C99 标准不同;这是所有这些问题的根源。 IDK 何时(如果有的话)VS 运行时已更新为使用 C99 版本。 -
MS 从未努力遵守 C99 - 是什么让您认为“Visual Studio 包含符合 C99 的 snprintf 版本”?
-
建议,用于验证实际发生的情况....编写一个小程序,将“超长”缓冲区传递给 snprintf(),然后使用调试器查看实际放置在结果缓冲区中的内容。
标签: c visual-studio-2015 c99