我想知道为什么MISRA:2012需要功能原型。在下面的示例中,这两个原型并不是必需的。
#include <stdio.h>
#include <stdlib.h>
// >>> Truly useless in my opinion
void display(void);
int main(void);
// <<<
void display(void) {
printf("Hello World!\n");
}
int main() {
display();
return EXIT_SUCCESS;
}
我能这么比如阅读的理由在这里对我来说并不很清楚。例如,如果main
尝试display
在声明之前进行访问,则编译器或静态分析器将引发错误:声明之前使用的函数显示。
换句话说,为该MISRA规则创建偏差是个好主意吗?
void display(void);
是函数前向声明。它具有原型格式。
如发布的链接中所示,函数原型是具有所有指定参数类型的函数声明。如果没有参数,则参数列表必须是(void)
(无参数)而不是()
(任何参数)。
确切的规则8.2说:
规则8.2函数类型必须是带有命名参数的原型形式
提供的基本原理(阅读它,很好)提到,这是为了避免未指定所有参数的旧K&R和C90程序。只要函数声明中的参数类型与函数定义中的参数类型不冲突,C99仍在某种程度上允许这样做。
本质上,该规则旨在禁止以下功能:
void func1 (x) // K&R style
int x;
{}
void func2(x) // sloppy style
{}
所有参数(如果有)必须指定类型和名称。
但是,我在MISRA-C中没有发现任何要求您为每个函数编写函数声明的内容。这意味着无论有没有函数声明,示例代码都将符合此MISRA规则。
尽管正如我在前面的答案中提到的那样,编写不带函数声明(原型格式)的.c文件是一种草率的实践。如果需要按特定顺序调用函数,则应通过程序设计,函数命名和注释/文档来使其清晰可见。并非按照它们在.c文件中声明的顺序排列。
在.c文件中声明函数的源代码行与该函数的行为/使用之间不应存在紧密的耦合。
相反,应按逻辑上合理的顺序定义功能。编写.c文件的一种常用方法是保留所有公共函数,这些函数的函数声明保存在.c文件顶部的.h文件中。然后,将内部功能(具有static
/内部链接的功能)置于底部。该模型需要所有内部函数的函数声明。另一种选择是将所有内部功能放在顶部,将公共功能放在底部。只要您保持一致,就可以。
最重要的是,如果.c文件中的函数定义重新排序,则它不应破坏程序或引起编译器错误。确保这一点的最简单方法是始终为程序中的每个函数提供函数声明。
请注意,文件顶部的函数声明根本不是“真正没用的”,因为它们提供了C文件中存在的所有函数的快速摘要。这是一种编写自文档代码的方法。
注意,作为特殊情况,C标准不允许main()的原型。
注意,此外,第8.7和8.8不允许你用void display(void)
不用static
,因为该函数在一个翻译单元只能使用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句