- Any exported function MUST be properly prototyped.
- Prototypes for exported function MUST appear in header files and
MUST NOT appear in source files.
- The source file which defines an exported function MUST include the
header file containing its prototype.
This layout is correct:
File my_string.h :
#ifndef MY_STRING_H_
# define MY_STRING_H_
# include <stddef.h>
size_t my_strlen(const char *);
char *my_strdup(const char *);
#endif /* !MY_STRING_H_ */
|
|
| File my_strlen.c :
#include "my_string.h"
size_t my_strlen(const char *s)
{
/* definition of my_strlen */
}
|
|
File my_strdup.c :
#include "my_string.h"
char *my_strdup(const char *s)
{
/* definition of my_strdup */
}
|
|
- Prototypes MUST conform to the ANSI C standard: they must specify
both the return type and the argument types.
- Prototypes SHOULD include argument names (in addition to their type).
These are invalid prototypes:
foo();
bar(int, long);
int baz();
|
|
These are valid prototypes:
int foo(int x);
void bar(int x, long y);
int baz(void);
|
|
- Within a block of prototypes, function names SHOULD be aligned.
This is inelegant:
unsigned int strlen(const char *);
char *strdup(const char *);
|
|
This is elegant:
unsigned int strlen(const char *);
char *strdup(const char *);
|
|
- Function names in prototypes SHOULD be aligned with other
declarations.
This is not recommended:
int gl_counter;
struct s_block *allocate(unsigned int size);
void release(struct s_block *);
|
|
This is recommended:
int gl_counter;
struct s_block *allocate(unsigned int size);
void release(struct s_block *);
|
|
- Function argument lists MAY be broken between each argument, after
the comma. When doing so, the arguments MUST be properly aligned.
This is correct:
type foo(type1 p1, type2 p2);
|
|
This is also correct:
type bar(type1 p1,
type2 p2,
type3 p3);
|
|
- Functions MUST NOT take more than 4 arguments.
Rationale: the C ABI on Unix specifies that the first
4 function arguments are always passed in registers, which yields more
performance. In addition, if more arguments are needed, usually
the modelling of the project is wrong.
- An argument name MAY be omitted at the point of definition of
a function, in the special case where it is not used by the function.
Rationale: by omitting an argument name, the compiler warning
saying that it is unused is inhibited.
- Functions SHOULD NOT return structures or unions by value. Structures or
unions SHOULD NOT be passed by value as function arguments, either.
The use of dynamic memory management is encouraged instead.
- Function arguments passed by reference SHOULD be declared
const
unless actually modified by the function.