-1

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

sprintf_s(var, outfile_ppm, local_filecounter++);

这里,varchar*类型,local_filecounterint类型。

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

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

这个警告是什么,我怎样才能摆脱它?

4

1 回答 1

7

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 的主要实现都是这样做的。事情可能已经改变。

于 2017-07-19T18:45:39.240 回答