Since I am mainly an Electrical Engineer, forgive me if I am somewhat off with some terminology.
I am currently programming a display driver/interface module. And like so many times before, I have reached a point where I am unsure on how to separate function prototypes and definitions that are meant for internal use of the module from the public interface.
Consider the following code as as an example:
C-file:
// display.c
#include "display.h"
// Belongs to public Interface
void SetFont(Font_t fnt) {
// implementation
}
// Belongs to public Interface
void PrintCharAt(int x, int y, char ch) {
// implementation
}
// For internal use only
void SendDataToDisplay(DisplayTelegram_t telegram) {
}
Header:
// display.h
typedef struct {
// implementation
} Font_t;
typedef struct {
// implementation
} DisplayTelegram_t;
void SetFont(Font_t fnt);
void PrintCharAt(int x, int y, char ch);
void SendDataToDisplay(DisplayTelegram_t telegram);
The article What Belongs in a C .h Header File? covers several points that I mostly agree with.
DO include in the header file all of the function prototypes for the public interface of the module it describes.
DON’T include in the header file any other function or macro that may lie inside the module source code. It is desirable to hide these internal “helper” functions inside the implementation. If it’s not called from any other module, hide it!
So far so good, but what is the best practice for hiding the internal prototypes etc? There is no reason to have the DisplayTelegram_t
type and the SendDataToDisplay()
prototype in the header. It may even confuse someone who just wants to use the interface when things get more complex.
I can think of three options:
Just put all internal prototypes, typedefs, defines etc. to the top of the .c-file. I have done this in the past, but I do not like it. It does not seem consistent to pollute the .c-file with header-material.
Create a second header file like
display_internal.h
and put everything for internal use only there. I have read a lot about this approach, but barely seen it used.Don't care about hiding internal prototypes etc. and just put everything in the header-file. Maybe grouping public and internal stuff together respectively and leaving a comment. This is dirty from a responsibility-perspective but at least its consistent and clean for the author of the code.
Is there any approach I am missing? How is this handled on a professional level?
static
the functions (or variables) that are internal to your compilation unit.