Forum: Compiler & IDEs AVR-GCC/ARM-GCC Struct "anonymisieren"


von Walter Tarpan (Gast)


Lesenswert?

Hallo zusammen,
ich stelle mir gerade die Frage, ob es möglich ist, in einer 
Header-Datei eine unvollständige Definition eines structs anzugeben. 
Hintergrund ist der, daß die Datentypen im Struct sehr viele 
Headerdateien brauchen, die für den Aufrufer wiederum völlig unnötig 
sind. Der Anwendungsfall sieht in etwa so aus:

Es gibt ein Modul, das aus einer Funktion besteht, die ein Struct 
erzeugt, und vielen Funktionen, die das Struct benötigen:
1
#include "largeHeader1.h"
2
#include "largeHeader2.h"
3
#include "largeHeader3.h"
4
#include "largeHeader4.h"
5
#include "modul1header.h"
6
7
typedef struct {
8
    needsHeader1_32_t a;
9
    needsHeader2_32_t b;
10
    needsHeader3_32_t c;
11
    needsHeader4_32_t d;
12
    needsHeader4_32_t e;
13
} box_t;
14
15
16
Box_t Init_Box( ... ) 
17
{
18
    [...]
19
}
20
21
22
uint_fast8_t herkules(Box_t *Box) 
23
{
24
    [...]
25
}
26
27
28
uint_fast8_t apollo(Box_t *Box) 
29
{
30
    [...]
31
}
32
33
34
uint_fast8_t zeus(Box_t *Box) 
35
{
36
    [...]
37
}
In einem anderen Modul finden sich die aufrufenden Funktionen:
1
#include "modul1header.h"
2
3
void pandora(void) 
4
{
5
    Box_t box1, box2, ... boxn;
6
    box1 = Init(..Parametern..);
7
    
8
    apollo(&box1);
9
    [...]
10
    herkules(&box1);
11
    [...]
12
}
Die aufrufende Funktion pandora() hat keinerlei Grund, selbst in ein 
struct vom Typ Box_t zu gucken - sie muß es nur aufbewahren. Deshalb 
müßte sie die genaue Deklaration von Box_t auch gar nicht kennen. Wenn 
sie sie kennt, kommt das "Übel", daß in diesem Modul auch die großen 
Headerdateien eingebunden werden müssen.

Gibt es dafür eine Standardlösung?
Oder ist das generell keine gute Idee?

Viele Grüße
W.T.

von Dr. Sommer (Gast)


Lesenswert?

Die komplette Definition von box_t wird nur benötigt wenn eine Instanz 
davon angelegt wird (zB auf dem Stack), um die Größe des structs zu 
kennen. Wenn überall nur mit Pointern auf box_t gearbeitet wird, 
reicht eine forward-Declaration:
1
struct box_t;
2
typedef struct box_t box_t;
Denn Pointer sind immer gleich groß.
Vor der 1. Verwendung wo die Größe des struct bekannt sein muss muss 
dann noch eine normale Definition folgen:
1
struct box_t {
2
  ...
3
};
Ähnlich funktioniert das "Pimpl design pattern", bei dem man den Pointer 
noch in ein "äußeres" struct packt das dann vom User Code verwendet 
wird.

Aber: C ist doch noch schön einfach zu kompilieren. Wie viel langsamer 
wird der Compile-Vorgang denn wenn du alle Header includest?

Precompiler header können auch helfen.

von Dr. Sommer (Gast)


Lesenswert?

Walter Tarpan schrieb:
> Die aufrufende Funktion pandora() hat keinerlei Grund, selbst in ein
> struct vom Typ Box_t zu gucken - sie muß es nur aufbewahren. Deshalb
> müßte sie die genaue Deklaration von Box_t auch gar nicht kennen.
Aber sie muss wissen wie groß das struct ist, um es auf dem Stack 
anlegen zu können. Daher muss sie die komplette Definition kennen.

von Walter Tarpan (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Ähnlich funktioniert das "Pimpl design pattern", bei dem man den Pointer
> noch in ein "äußeres" struct packt das dann vom User Code verwendet
> wird.
>

Danke, mit dem Stichwort habe ich wieder mehr Such-Möglichkeiten.


Dr. Sommer schrieb:
> Aber: C ist doch noch schön einfach zu kompilieren. Wie viel langsamer
> wird der Compile-Vorgang denn wenn du alle Header includest?

Fast gar nicht. Aber ich muß für die (plattformspezifischen) 
Headerdateien Dummies für den Modultest schreiben.

von Dr. Sommer (Gast)


Lesenswert?

Walter Tarpan schrieb:
> Fast gar nicht. Aber ich muß für die (plattformspezifischen)
> Headerdateien Dummies für den Modultest schreiben.
Vielleicht einfach per #ifdef die entsprechenden Felder aus dem struct 
weglassen, wenn da dann eh nur dummies reinkämen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.