In the link provided- https://embeddedgurus.com/barr-code/2010/11/what-belongs-in-a-c-h-header-file/
Michael Barr states the following:
DON’T expose the internal format of any module-specific data structure passed to or returned from one or more of the module’s interface functions. That is to say there should be no “struct { … } foo;” code in any header file. If you do have a type you need to pass in and out of your module, so client modules can create instances of it, you can simply “typedef struct foo moduleb_type” in the header file. Client modules should never know, and this way cannot know, the internal format of the struct.
What I understand is that if there is a module say "led" wants to be used by a client module, say "main", main module should not know the inner workings of module "led". Here is what I did following the advice but it just seems impossible to implement it:
led.c:
#include "led.h"
typedef enum
{
RED = 0,
GREEN
} e_LedColor_t;
typedef enum
{
FAST = 0,
SLOW,
DIRECT,
OFF,
HEARTBEAT,
DOUBLE_BLINK,
IDENTIFICATION
} e_LedMode_t;
struct Led
{
e_LedColor_t color;
e_LedMode_t mode;
};
led.h:
#ifndef LED_H
#define LED_H
typedef struct Led led_t;
#endif
main.c
#include "led.h"
int main() {
led_t led;
return 1;
}
I receive the error on line led_t led; in main saying:
error: field has incomplete type 'ledt_t'(aka 'struct led')
Just because the main module cannot recognize a definition for the Led struct, it throws an error. But if I do a definition, then the whole idea of encapsulation is lost. There must be something that I misunderstand but I do not know what it is. Can anyone help me?