我有一堆用 C 语言编写的可执行文件,这些可执行文件使用 Polyspace Code Prover 和 Bug Finder 进行了静态分析。这两个工具都将我的 main()
函数标记为违反 MISRA 准则 8.4,并显示以下消息:
“当定义具有外部链接的对象或函数时,兼容声明应可见。 函数“main”在定义时没有可见的兼容原型(prototype)。”
前向声明 main()
似乎解决了这个问题,但这对我来说非常“奇怪”,并且在使用 Doxygen 记录项目时引入了问题。
函数如下:
int main(int argument_counter, char const *arg_vector[])
同样如您所见,我们不能使用传统的 argc
和 argv[]
参数名称,因为它们与它在外部找到的一些变量太相似了标题,在我看来这也是 super 奇怪的。
这是代码问题还是工具配置有问题?
最佳答案
当您使用实现定义的表单时,您经常会从有关 main
的静态分析器中得到此类误报。但值得注意的是,一个严格符合要求的托管程序应使用这种形式:
int main(int argc, char *argv[])
参数的名称并不重要,但它们的类型很重要。 char* []
与 const char* []
不是同一类型。代码中的 const
不会将实际字符数组标记为 const
,而是将指向它们的指针数组标记为 const
。这有点奇怪,我真的不明白为什么有人会试图覆盖这些。
同样值得注意的是,argc
和 argv
必须 在严格符合 C17 5.1.2.2.1 §2 的程序中是可写的:
The parameters
argc
andargv
and the strings pointed to by theargv
array shall be modifiable by the program, and retain their last-stored values between program startup and program termination
因此,理想情况下,您应该将类型更改为严格符合程序所需的类型。
但是,许多 C 程序并不严格符合托管程序,因此静态分析器也必须能够吞并 main
的实现定义形式。前向声明 main
也没有什么坏处——你可以安全地假设编译器不会这样做(C17 5.1.2.2.1 §1 “实现声明没有
此功能的原型(prototype)。”)。
假设您有实现定义的形式 void main (void)
。要使工具静音,您只需编写:
void main (void);
void main (void)
{ ...
我强烈怀疑工具警告的原因是它太生硬了,无法识别 main
是一个特例。同样,如果使用 int
作为 main
的返回值,而不是 int32_t
,您会收到警告 - 这是误报,因为 MISRA-C 有main
返回类型的显式异常。
关于c - Polyspace 警告不转发声明 main(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53495821/