Polyspace 警告不转发声明 main()

Polyspace alerts for not forward declaring main()

我有一堆用 C 编写的可执行文件,这些可执行文件使用 Polyspace Code Prover 和 Bug Finder 进行了静态分析。这两个工具都将我的 main() 函数标记为违反 MISRA 准则 8.4,并显示以下消息:

"当定义了 object 或具有外部链接的函数时,兼容的声明应该是可见的。 函数 'main' 在定义时没有可见的兼容原型。"

前向声明 main() 似乎可以解决问题,但这对我来说非常 "weird" 并且在使用 Doxygen 记录项目时会引入问题。

函数如下:

int main(int argument_counter, char const *arg_vector[])

同样如您所见,我们不能使用传统的 argcargv[] 参数名称,因为它们与它在外部 headers 上找到的一些变量太相似了,这在我看来也是超级奇怪的。

这是代码问题还是工具配置有问题?

当您使用实现定义的表单时,您经常会从有关 main 的静态分析器中得到此类误报。但值得注意的是,严格符合托管程序应使用这种形式:

int main(int argc, char *argv[])

参数的名称并不重要,但它们的类型很重要。 char* []const char* [] 不是同一类型。您代码中的 const 不会将实际字符数组标记为 const,而是将指向它们的指针数组标记为 const。这有点奇怪,我真的不明白为什么有人会试图覆盖这些。

同样值得注意的是,argcargv 必须 在严格符合 C17 5.1.2.2.1 §2 的程序中是可写的:

The parameters argc and argv and the strings pointed to by the argv 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 “实现声明不 此函数的原型。”)。

假设您有实现定义的形式 void main (void)。要使工具静音,您可以简单地写:

void main (void);
void main (void)
{ ...

我强烈怀疑工具警告的原因是它太生硬了,无法识别 main 是一个特例。同样,如果使用 int 作为 main 的 return 值而不是 int32_t,您会收到警告 - 这是误报,因为 MISRA-C 有一个明确的例外return 类型 main

main() 是许多规则的例外,无论是在 MISRA 内还是在不...

为避免疑义,MISRA C:2012 Technical Corrigendum 1main() 添加了规则 8.4 的明确例外:

The function main need not have a separate declaration.