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[])
同样如您所见,我们不能使用传统的 argc
和 argv[]
参数名称,因为它们与它在外部 headers 上找到的一些变量太相似了,这在我看来也是超级奇怪的。
这是代码问题还是工具配置有问题?
当您使用实现定义的表单时,您经常会从有关 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
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 1 为 main()
添加了规则 8.4 的明确例外:
The function main need not have a separate declaration.
我有一堆用 C 编写的可执行文件,这些可执行文件使用 Polyspace Code Prover 和 Bug Finder 进行了静态分析。这两个工具都将我的 main()
函数标记为违反 MISRA 准则 8.4,并显示以下消息:
"当定义了 object 或具有外部链接的函数时,兼容的声明应该是可见的。 函数 'main' 在定义时没有可见的兼容原型。"
前向声明 main()
似乎可以解决问题,但这对我来说非常 "weird" 并且在使用 Doxygen 记录项目时会引入问题。
函数如下:
int main(int argument_counter, char const *arg_vector[])
同样如您所见,我们不能使用传统的 argc
和 argv[]
参数名称,因为它们与它在外部 headers 上找到的一些变量太相似了,这在我看来也是超级奇怪的。
这是代码问题还是工具配置有问题?
当您使用实现定义的表单时,您经常会从有关 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 “实现声明不
此函数的原型。”)。
假设您有实现定义的形式 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 1 为 main()
添加了规则 8.4 的明确例外:
The function main need not have a separate declaration.