范围内没有原型定义的函数的编译器警告?

Compiler warning for function defined without prototype in scope?

[问题灵感来自 的评论线程。]

众所周知,自C99以来调用未声明的函数是错误的,最好有适当的原型。

但是,除此之外,我希望我的编译器在我 定义 范围内没有原型声明的函数时警告我,大概包含在与来电者正在使用。 (除非函数是静态的,在这种情况下所有这些都没有实际意义。)

原因很明显:如果头文件中有原型声明,并且所有调用者都包含它,但它不包含在定义函数的文件中,并且函数的实际定义与外部原型,那么代表调用者所做的所有原型检查都是毫无价值的,实际上适得其反。有一个明显的错误,但不能保证完全被捕获。

有没有通用的编译器可以检查这个?我用 -Wall 尝试了 gcc 和 clang,但他们没有。 (我想 Gimpel lint——如果它还在——会这样做,但我没有副本。)

理想情况下,我希望它也坚持原型存在于单独的头文件中,但那是另一回事,所以我不坚持。 (这个附加规定的原因是一些程序员,被假设的警告消息所困扰,可能会试图通过在包含定义的 .c 文件顶部键入外部原型来使其静音,再次,会破坏目的。)

如果您需要一个同时适用于 gcc 和 clang 的选项,您最好的选择可能是 -Wmissing-prototypes。如 gcc 文档中所示,如果定义了全局函数并且满足以下任一条件,这将触发:

  • 之前没有申报;或

  • 之前的声明没有原型。

如果前面的声明与定义包含在同一个文件中,则不会报错;也就是说,它不要求声明在头文件中。

必须明确启用此选项; -Wall-Wextra 均未启用它。

不幸的是,gcc 只允许 C 和 Objective C 使用该选项;不适用于 C++(可能是因为 C++ 不允许非原型函数声明)。对于 gcc,另一种可能性是 -Wmissing-declarations。仅当没有先前的声明时才会产生此警告;没有报告先前没有原型的声明(即 int foo();)。但它适用于 C 和 C++。同样,必须明确启用警告选项。

Clang 也有一个 -Wmissing-declarations 选项,但它的含义完全不同,它会自动启用(即使没有 -W 选项)。例如,此选项控制有关空声明 (int;)、空类型定义 (typedef int;) 和未声明任何对象的未标记复合 (struct { int a; };) 的投诉。 Gcc 还会发出有关这些构造的警告,但没有明显的选项来启用或禁用这些警告。