sprintf_s()隐式声明警告

时间:2017-07-19 18:11:27

标签: c c11 tr24731

我有一个C代码,我有这一行。

sprintf_s(var, outfile_ppm, local_filecounter++);

此处,varchar*类型,local_filecounterint类型。

当我运行代码时,它会给我这个警告:

  

警告:函数'sprintf_s'的隐式声明在C99中无效[-Wimplicit-function-declaration]

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

1 个答案:

答案 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 的主要实现是这样做的,无论宏的存在如何。事情可能已经发生了变化。