我有一堆用C编写的可执行文件,可通过Polyspace Code Prover和Bug Finder进行静态分析。这两个工具都将我的main()
函数标记为违反MISRA准则8.4,并显示以下消息:
”当定义了具有外部链接的对象或函数时,兼容的声明应可见。 函数“ main”在定义时没有可见的兼容原型。”
向前声明main()
似乎可以解决问题,但这对我来说很“奇怪”,并且在用Doxygen记录项目时会带来问题。
功能如下:
int main(int argument_counter, char const *arg_vector[])
也如您所见,我们无法使用传统的argc
和argv[]
参数名称,因为它们与在外部标头上找到的某些变量太相似,这在我的书中也很奇怪意见。
这是代码问题还是工具配置有问题?
答案 0 :(得分:4)
使用实现定义的形式时,您经常会从静态分析器中得到关于main
的这类误报。但值得注意的是,严格符合要求的托管程序应使用以下形式:
int main(int argc, char *argv[])
参数名称无关紧要,但它们的类型无关紧要。 char* []
与const char* []
的类型不同。代码中的const
不会将实际的字符数组标记为const
,而是将指向它们的指针数组标记为。这有点奇怪,我真的不明白为什么有人会尝试覆盖这些内容。
同样值得注意的是,argc
和argv
必须在严格符合标准的程序C17 5.1.2.2.1§2中可以写:
参数
argc
和argv
以及argv
数组指向的字符串应 可由程序修改,并在程序之间保留其最后存储的值 启动和程序终止
因此,理想情况下,您应该将类型更改为严格符合程序要求的类型。
但是,许多C程序不是严格符合托管程序的,因此静态分析器也必须能够吞并main
的实现定义形式。向前声明main
也没有任何害处-您可以放心地认为编译器也不会这样做(C17 5.1.2.2.1§1“实现未声明
该功能的原型。”)。
假设您具有实现定义的形式void main (void)
。要使该工具静音,您只需编写:
void main (void);
void main (void)
{ ...
我强烈怀疑发出该工具警告的原因是太钝了,无法认识到main
是特例。同样,您可能会收到有关将int
用作main
而不是int32_t
的返回值的警告-这是误报,因为MISRA-C对于{ {1}}。
答案 1 :(得分:2)
main()
是MISRA内部和没有...的许多规则的例外。
为免生疑问,MISRA C:2012 Technical Corrigendum 1在规则8.4中为main()
添加了一个明确的例外:
函数main不需要单独的声明。