【问题标题】:sprintf_s() implicit declaration warning [closed]sprintf_s()隐式声明警告[关闭]
【发布时间】:2017-07-19 18:11:26
【问题描述】:

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

sprintf_s(var, outfile_ppm, local_filecounter++);

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

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

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

这是什么警告,我该如何消除它?

【问题讨论】:

  • “我怎样才能摆脱它?” --> 不要使用sprintf_s() 发布似乎需要它的代码以查看替代方案。
  • 这个sprintf_s 函数到底是什么,你从哪里得到的?包含正确的标题,警告就会消失。
  • @DietrichEpp 那里也不需要#define __STDC_WANT_LIB_EXT1__ 1 吗?
  • 标准 C99 没有 sprintf_s()。 C11 可以包含它。其他版本可能会将其作为某种形式的扩展。
  • @AnttiHaapala:根据标准,是的。但是,我不知道宏实际上具有这种效果的任何实现。

标签: c c11 tr24731


【解决方案1】:

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 中。给出的流行解释是,这些函数由 Microsoft在内部使用,在他们自己的代码库中来解决安全问题。

其他实现依赖于 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) 来计算其大小,并且在用作函数参数时数组衰减为指针的常见警告适用于此。

总结:你不能使用sprintf_s(),除非你切换到Visual Studio或者自己实现。硬饼干。

小提示:理论上,如果你想要sprintf_s,你应该定义__STDC_WANT_LIB_EXT1__。然而,在实践中,唯一定义 sprintf_s at all 的主要实现不管宏是否存在——据我所知。事情可能已经改变了。

【讨论】:

    猜你喜欢
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    相关资源
    最近更新 更多