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

Ste*_*mit 4 c lint compiler-warnings gcc-warning function-prototypes

[ 此答案的注释线程启发了这个问题。]

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

但是,除此之外,如果我定义的函数在范围内没有原型声明,并且希望包含在调用者使用的同一头文件中,那么我希望编译器警告我。(除非该函数是静态的,否则所有这些都是没有意义的。)

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

有通用的编译器可以检查吗?我用-Wall尝试了gcc和clang,但他们没有。(我可以想象,如果Gimpel皮棉仍然存在,它会这样做,但我没有副本。)

理想情况下,我希望它也坚持认为原型存在于单独的头文件中,但是那是一回事,所以我不必坚持。(之所以做出这样的附加规定,是因为一些程序员对假设的警告消息感到厌倦,他们可能会试图通过在.c包含该定义的文件顶部键入一个外部原型来使其静音,这又会破坏目的。 )

ric*_*ici 5

如果您需要同时在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(typedef int;)和未加标签的组合的投诉struct { int a; };。Gcc还会发出有关这些构造的警告,但是没有明显的选项可以启用或禁用这些警告。