Canonical Function Structure
Here is a proposed canonical structure for functions/procedures. Clearly in some cases some sections would not be present. What’s important is to understand the basic phasing of the work to be done and the separation of tasks.
int foo(
char *StringIn, // “in” parameter
size_t BufferLength, // “in” parameter
char Buffer[], // “out” parameter, max length governed by BufferLength
size_t *CharsWritten // “out” parameter, must be <= BufferLength
) {
// Phase 1: Initialize out parameters
*CharsWritten = 0;
// Phase 2: Capture and validate parameters
const size_t StringInLength = strlen(StringIn);
if ((BufferLength != 0) && (Buffer == NULL))
return ERR_INVALID_PARAMETER;
// Phase 3: do work
if (BufferLength <= StringInLength)
return ERR_BUFFER_TOO_SMALL;
memcpy(Buffer, StringIn, StringInLength);
Buffer[StringInLength] = ‘\0’;
// Phase 4: copy data out
*CharsWritten = StringInLength + 1; // safe because BufferLength is > StringInLength so “+1” won’t overflow
// Phase 5: goodbye
return ERR_SUCCEEDED;
}
There may be other phases and the example’s perhaps kind of dumb but I think it works well to call out what kinds of operations should happen in which phases and even more so what doesn’t have to happen later on given work that occurred earlier.