2017-07-19 398 views
-1

我有一个C代码,我有这条线。sprintf_s()隐式声明警告

sprintf_s(var, outfile_ppm, local_filecounter++); 

这里,var是char类型,local_filecounter是int类型。

当我运行代码,它给了我这样的警告:

警告:函数“sprintf_s”隐式声明是无效的C99 [-Wimplicit函数声明]

是什么这个警告,我该如何摆脱它?

+2

“我该如何摆脱它?” - >不要使用'sprintf_s()'发布看起来需要它的代码来查看备选方案。 – chux

+0

我需要使用它。 – npatel

+0

快速&肮脏的方式:添加'-Wnoimplicit-function-declaration'到编译器选项。 – ForceBru

回答

4

sprintf_s函数是附件K/TR 24731边界检查接口的一部分。但是,对这些接口感兴趣的人应阅读N1967 Field Experience With Annex K — Bounds Checking Interfaces。下面是摘录:

尽管从原来的建议十余年,自ISO/IEC TR 24731-1的批准近十年:2007年,由于引入了边界检查接口的将近五年进入C标准,没有出现可行的符合实现。 API仍然存在争议,实施者仍然拒绝执行请求。

事实上,如果你看一下GCC C11 status page,你会看到(强调):

边界检查(附录K)[可选]:图书馆问题(未实现)

附录K(sprintf_s和其他类似_s版本的函数)的唯一主要实现是在Visual Studio中。给出的流行解释是微软在他们自己的代码库内部使用这些函数来解决安全问题。其他实现依赖于像Valgrind,mudflap,地址清理器等工具来解决同样的问题,并且微软以外的代码库实际上并没有使用这些函数,所以实现它们的动机很小。

换句话说,如果您不使用Visual Studio,则无法使用这些功能。幸运的是,它们不是必需的。

sprintf_s在问题的调用是高度怀疑与...

// Wait, what? Something smells fishy... 
sprintf_s(var, outfile_ppm, local_filecounter++); 

开始的第三个参数sprintf_s应该是一个格式字符串,但local_filecounter++看起来太可疑是一个格式字符串。

通常情况下,您可以使用snprintf,将其输出截断以适应缓冲区,如果您使用C标准之外的函数,则可以使用asprintf

char var[256]; 
snprintf(var, sizeof(var), outfile_ppm, localfile_counter++); 

注意,如果var没有数组类型,你不能使用sizeof(var)使用时,作为函数的参数适用于这里来计算它的大小,以及约腐烂数组的指针通常的注意事项。

摘要:除非切换到Visual Studio或自己实现,否则不能使用sprintf_s()。坚果饼干。

小注:从理论上讲,如果你想sprintf_s,你应该定义__STDC_WANT_LIB_EXT1__。然而,在实践中,只要我知道,无论宏的存在如何,定义sprintf_s的所有都是如此。事情可能已经改变。