sprintf_s() 隐式声明警告
sprintf_s() implicit declaration warning
我有一个 C 代码,其中有这一行。
sprintf_s(var, outfile_ppm, local_filecounter++);
这里,var
是char*
类型,local_filecounter
是int
类型。
当我 运行 代码时,它会给我这个警告:
warning: implicit declaration of function 'sprintf_s' is invalid in C99 [-Wimplicit-function-declaration]
这个警告是什么,我该如何摆脱它?
sprintf_s
函数是附件 K/TR 24731 边界检查接口的一部分。但是,任何对这些接口感兴趣的人都应该阅读 N1967 Field Experience With Annex K — Bounds Checking Interfaces。以下是摘录:
Despite more than a decade since the original proposal and nearly ten years since the ratification of ISO/IEC TR 24731-1:2007, and almost five years since the introduction of the Bounds checking interfaces into the C standard, no viable conforming implementations has emerged. The APIs continue to be controversial and requests for implementation continue to be rejected by implementers.
的确,如果您查看 GCC C11 status page,您会看到(强调):
Bounds-checking (Annex K) [Optional]: Library issue (not implemented)
附件 K(sprintf_s
和其他类似 _s
版本的函数)的唯一主要实现在 Visual Studio 中。给出的流行解释是,这些函数由 Microsoft 内部使用,在他们自己的代码库中 来解决安全问题。
其他实现依赖于 Valgrind、mudflap、address sanitizer 等工具来解决同一组问题,Microsoft 以外的代码库很少实际使用这些功能,因此实现它们的动力很小.
换句话说,如果您不使用Visual Studio,则无法使用这些功能。幸运的是,它们不是必需的。
问题中对 sprintf_s
的调用高度怀疑是从...
开始的
// Wait, what? Something smells fishy...
sprintf_s(var, outfile_ppm, local_filecounter++);
sprintf_s
的第三个参数应该是格式字符串,但 local_filecounter++
看起来太可疑了,不可能是格式字符串。
通常,您会使用 snprintf
,它会截断其输出以适合缓冲区,或者 asprintf
如果您可以使用 C 标准之外的函数。
char var[256];
snprintf(var, sizeof(var), outfile_ppm, localfile_counter++);
请注意,如果 var
没有数组类型,则您不能使用 sizeof(var)
来计算其大小,关于数组在用作函数参数时衰减为指针的常见注意事项适用于此。
总结:你不能使用sprintf_s()
除非你切换到Visual Studio或者你自己实现它。硬饼干。
小注:理论上要sprintf_s
就应该定义__STDC_WANT_LIB_EXT1__
。然而,实际上,据我所知,唯一定义 sprintf_s
at all 的主要实现与宏的存在无关。事情可能已经改变了。
我有一个 C 代码,其中有这一行。
sprintf_s(var, outfile_ppm, local_filecounter++);
这里,var
是char*
类型,local_filecounter
是int
类型。
当我 运行 代码时,它会给我这个警告:
warning: implicit declaration of function 'sprintf_s' is invalid in C99 [-Wimplicit-function-declaration]
这个警告是什么,我该如何摆脱它?
sprintf_s
函数是附件 K/TR 24731 边界检查接口的一部分。但是,任何对这些接口感兴趣的人都应该阅读 N1967 Field Experience With Annex K — Bounds Checking Interfaces。以下是摘录:
Despite more than a decade since the original proposal and nearly ten years since the ratification of ISO/IEC TR 24731-1:2007, and almost five years since the introduction of the Bounds checking interfaces into the C standard, no viable conforming implementations has emerged. The APIs continue to be controversial and requests for implementation continue to be rejected by implementers.
的确,如果您查看 GCC C11 status page,您会看到(强调):
Bounds-checking (Annex K) [Optional]: Library issue (not implemented)
附件 K(sprintf_s
和其他类似 _s
版本的函数)的唯一主要实现在 Visual Studio 中。给出的流行解释是,这些函数由 Microsoft 内部使用,在他们自己的代码库中 来解决安全问题。
其他实现依赖于 Valgrind、mudflap、address sanitizer 等工具来解决同一组问题,Microsoft 以外的代码库很少实际使用这些功能,因此实现它们的动力很小.
换句话说,如果您不使用Visual Studio,则无法使用这些功能。幸运的是,它们不是必需的。
问题中对 sprintf_s
的调用高度怀疑是从...
// Wait, what? Something smells fishy...
sprintf_s(var, outfile_ppm, local_filecounter++);
sprintf_s
的第三个参数应该是格式字符串,但 local_filecounter++
看起来太可疑了,不可能是格式字符串。
通常,您会使用 snprintf
,它会截断其输出以适合缓冲区,或者 asprintf
如果您可以使用 C 标准之外的函数。
char var[256];
snprintf(var, sizeof(var), outfile_ppm, localfile_counter++);
请注意,如果 var
没有数组类型,则您不能使用 sizeof(var)
来计算其大小,关于数组在用作函数参数时衰减为指针的常见注意事项适用于此。
总结:你不能使用sprintf_s()
除非你切换到Visual Studio或者你自己实现它。硬饼干。
小注:理论上要sprintf_s
就应该定义__STDC_WANT_LIB_EXT1__
。然而,实际上,据我所知,唯一定义 sprintf_s
at all 的主要实现与宏的存在无关。事情可能已经改变了。