我有一个C代码,我有这一行。
sprintf_s(var, outfile_ppm, local_filecounter++);
此处,var
为char*
类型,local_filecounter
为int
类型。
当我运行代码时,它会给我这个警告:
警告:函数'sprintf_s'的隐式声明在C99中无效[-Wimplicit-function-declaration]
这是什么警告,如何摆脱它?
答案 0 :(得分:5)
sprintf_s
函数是Annex K / TR 24731边界检查接口的一部分。但是,对这些界面感兴趣的任何人都应该阅读N1967 Field Experience With Annex K — Bounds Checking Interfaces。这是一段摘录:
尽管自最初的提案已有十多年,自ISO / IEC TR 24731-1:2007批准以来近十年,以及将Bounds检查接口引入C标准近五年,但没有可行的符合性实现已经出现。 API继续存在争议,实施请求继续被实施者拒绝。
事实上,如果你看一下GCC C11 status page,你会看到(强调添加):
界限检查(附件K)[可选]:图书馆问题(未实施)
附件K(sprintf_s
和其他类似_s
版本的函数)的唯一主要实现是在Visual Studio中。给出的流行解释是,Microsoft 在内部,在他们自己的代码库中使用这些函数来解决安全问题。
其他实现依赖于Valgrind,mudflap,地址清理程序等工具来解决同一组问题,而Microsoft以外的代码库实际上很少使用这些函数,因此实现它们的动机很少。 / p>
换句话说,如果您不使用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)
来计算其大小,并且当用作函数参数时,关于数组衰减为指针的常见警告适用于此处。
摘要:除非您切换到Visual Studio或自行实施,否则无法使用sprintf_s()
。坚韧的饼干。
次要注意事项:理论上,如果您需要__STDC_WANT_LIB_EXT1__
,则应定义sprintf_s
。然而,在实践中,据我所知,唯一一个定义sprintf_s
的的主要实现是这样做的,无论宏的存在如何。事情可能已经发生了变化。