Here is the declaration
dll_DoublyLinkedNode *dll_search(const dll_DoublyLinkedList list, void *key, int (*compare)(void *data, void *key)){
Should I split it? Should I just leave it as it is? Perhaps I should do something different?
The function body has three parts: an optional declarative part, an executable part, and an optional exception-handling part.
A function definition requires all parts of the function: a header (which includes the function return type, the function's name, and an argument list) and a function body.
A function declaration introduces an identifier that designates a function and, optionally, specifies the types of the function parameters (the prototype). Function declarations (unlike definitions) may appear at block scope as well as file scope.
When we place it in a function definition (in the local declaration section), the prototype is called a local prototype. Such declarations are primarily used by the functions containing them. The place of declaration of a function defines a region in a program in which the function may be used by other functions.
This is completely a matter of taste, but I'd be a fan of something along the lines of:
dll_DoublyLinkedNode *dll_search(
const dll_DoublyLinkedList list,
void *key,
int (*compare)(void *data, void *key)
){
Additionally, you could typedef the function pointer type you reference and give it a handy name.
There are many conventions for writing large function declarations in C. Here are some of the most common ones:
/////////////////////////////
// Type // Meaning ///
/////////////////////////////
// `.` // Single space //
// `-|` // Half an indent //
// `->` // Full indent //
/////////////////////////////
// One line
static inline int namespace_class_method(class_t *self, a_t a, b_t b, c_t c);
// Traditional C
static inline int namespace_class_method(self, a, b, c)
..class_t *self;
..a_t a;
..b_t b;
..c_t c;
{
../* Traditional K&R C had no declarations */
}
// Line wrapping
static inline int namespace_class_method(class_t *self, a_t a,
b_t b, c_t c);
// Naive
static inline int namespace_class_method(class_t *self, a_t a,
--->b_t b, c_t c);
// Linux, VIM[1]
static inline int namespace_class_method(class_t *self, a_t a,
........b_t b, c_t c);
// GNU
static inline int
namespace_class_method(class_t *self, a_t a,
.......................b_t b, c_t c);
// Java[2]
static inline int
namespace_class_method
-|(
--->class_t *self,
--->a_t a,
--->b_t b,
--->c_t c
-|);
// Haskell style
static inline int
namespace_class_method
-|( class_t *self
-|, a_t a
-|, b_t b
-|, c_t c );
Chose one and stick to it. Consistency and readability are more important than religion and style.
[1]: With cindent
, turned on for C/C++ by default.
[2]: Not sure if it was in Java, JavaScript, or somewhere else, but I've seen this one used extensively before.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With