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

时间:2018-05-17 22:00:38

标签: c compiler-warnings lint gcc-warning function-prototypes

[问题的灵感来自this answer的评论主题。]

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

但是,除此之外,我希望我的编译器警告我,如果我定义一个没有范围内的原型声明的函数,可能包含在调用者正在使用的相同头文件中。 (除非函数是静态的,在这种情况下所有这一切都没有实际意义。)

原因应该是显而易见的:如果标题中有原型声明,并且所有调用者都包含它,但它不包含在定义函数的文件中,并且函数的实际定义在某种程度上与外部不同原型,然后代表呼叫者完成的所有原型检查都是毫无价值的,实际上是适得其反的错误。有一个明显的错误,但它并不能保证完全被捕获。

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

理想情况下,我希望它还坚持原型存在于一个单独的头文件中,但那是不同的鱼,所以我不坚持。 (这个额外规定的原因是一些程序员,在假设的警告信息的帮助下,可能会试图通过在包含定义的.c文件顶部输入一个外部原型来使其静音,会打败这个目的。)

1 个答案:

答案 0 :(得分:4)

如果您需要一个适用于gcc和clang的选项,那么最好的选择可能是associating images with pages。如gcc文档中所示,如果定义了全局函数,则会触发此操作:

  • 之前没有声明;或

  • 之前的声明没有原型。

如果先前的声明包含在与定义相同的文件中,则不会抱怨;也就是说,它不要求声明在头文件中。

必须明确启用此选项;它既未由-Wall启用,也未由-Wextra启用。

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

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