I am wondering why function prototypes are required by MISRA:2012. In the example below, the two prototypes aren't really necessary.
#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;
}
The rationale I can read on SO such as here isn't very clear to me. For instance, if main
tries to access display
before it is declared, the compiler or the static analyzer will raise an error: function display used before declaration.
In other words is it a good idea to create a deviation for this MISRA rule?
void display(void);
is a function forward declaration. It has prototype format.
As indicated in the link posted, a function prototype is a function declaration with the types of all parameters specified. If there are no parameters, then the parameter list must be (void)
(no parameters) and not ()
(any parameter).
The exact rule 8.2 says:
Rule 8.2 Function types shall be in prototype form with named parameters
The rationale provided (read it, it is pretty good) mentions that this is to avoid old K&R and C90 programs where not all parameters are specified. C99 still allows this at some extent, as long as the parameter types in the function declaration don't collide with the parameter types in the function definition.
Essentially, the rule seeks to ban these kind of functions:
void func1 (x) // K&R style
int x;
{}
void func2(x) // sloppy style
{}
All parameters (if any) must have types and names specified.
However, I find nothing in MISRA-C that requires you to write a function declaration for each function. This means that your example code would conform to this MISRA rule with or without the function declaration.
Though as I mentioned in a previous answer, writing .c files without function declarations (in prototype format) is sloppy practice. If your functions need to be called in a certain order, it should be made obvious by the program design, function naming and comments/documentation. Not by the order that they happen to be declared inside the .c file.
There should be no tight coupling between the source code line where a function is declared in the .c file and that function's behavior/use.
Instead, functions should be defined in an order that makes sense logically. A common way to write .c files is to keep all public functions, that have their function declaration up in the .h file, at the top of the .c file. Then let the internal functions (those with static
/internal linkage) sit at the bottom. This model requires function declarations of all the internal functions. Another option is to put all internal functions on top, and the public functions at the bottom. As long as you are consistent, either is fine.
What's most important is that if function definitions inside the .c file are re-ordered, it should not break the program or cause compiler errors. The easiest way to ensure this is to always provide function declarations for every single function in your program.
Note that the function declarations on top of the file is not "truly useless" at all, as they provide a quick summary of all functions present in the C file. It is a way to write self-documenting code.
Note that the C standard allows no prototype for main(), as a special case.
Note that in addition, rule 8.7 and 8.8 disallows you to use void display(void)
without static
, since the function is only used in one translation unit.