我有一个 C 代码,其中有这一行。
sprintf_s(var, outfile_ppm, local_filecounter++);
这里,var
是char*
类型,local_filecounter
是int
类型。
当我运行代码时,它给了我这个警告:
警告:函数“sprintf_s”的隐式声明在 C99 [-Wimplicit-function-declaration] 中无效
这个警告是什么,我怎样才能摆脱它?
该sprintf_s
功能是附件 K/TR 24731 边界检查接口的一部分。然而,任何对这些接口感兴趣的人都应该阅读N1967 Field Experience With Annex K - Bounds Checking Interfaces。这是一段摘录:
尽管距离最初的提案已有十多年,距离 ISO/IEC TR 24731-1:2007 的批准已有近十年,距离将边界检查接口引入 C 标准已有近五年,但还没有出现可行的符合要求的实现. API 继续存在争议,实施请求继续被实施者拒绝。
确实,如果您查看GCC C11 状态页面,您会看到(添加了重点):
边界检查(附件 K)[可选]:库问题(未实现)
sprintf_s
附件 K(和其他类似_s
版本的函数)的唯一主要实现是在 Visual Studio 中。给出的流行解释是,这些函数由微软内部使用,在他们自己的代码库中解决安全问题。
其他实现依赖于 Valgrind、mudflap、地址清理器等工具来解决同一组问题,而且微软以外的代码库很少真正使用这些功能,因此实现它们的动机很小。
换句话说,如果您不使用 Visual Studio,则无法使用这些功能。幸运的是,它们不是必需的。
问题中的调用sprintf_s
很可能以......开始......</p>
// 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或者自己实现,否则无法使用。坚韧的饼干。
小注:理论上,__STDC_WANT_LIB_EXT1__
如果需要,您应该定义sprintf_s
. 然而,实际上,据我所知,无论宏是否存在,唯一定义sprintf_s
的主要实现都是这样做的。事情可能已经改变。