[问题的灵感来自this answer的评论主题。]
众所周知,自C99以来,调用尚未声明的函数是错误的,最好使用适当的原型。
但是,除此之外,我希望我的编译器警告我,如果我定义一个没有范围内的原型声明的函数,可能包含在调用者正在使用的相同头文件中。 (除非函数是静态的,在这种情况下所有这一切都没有实际意义。)
原因应该是显而易见的:如果标题中有原型声明,并且所有调用者都包含它,但它不包含在定义函数的文件中,并且函数的实际定义在某种程度上与外部不同原型,然后代表呼叫者完成的所有原型检查都是毫无价值的,实际上是适得其反的错误。有一个明显的错误,但它并不能保证完全被捕获。
是否有常见的编译器可以检查这个?我用-Wall尝试了gcc和clang,但他们没有。 (我会想象Gimpel lint - 如果它仍然存在 - 会这样做,但我没有副本。)
理想情况下,我希望它还坚持原型存在于一个单独的头文件中,但那是不同的鱼,所以我不坚持。 (这个额外规定的原因是一些程序员,在假设的警告信息的帮助下,可能会试图通过在包含定义的.c
文件顶部输入一个外部原型来使其静音,会打败这个目的。)
答案 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还会发出有关这些构造的警告,但没有明显的选项来启用或禁用这些警告。