Headerdatei und C Datei: includes

Gast #1411278
Hallo,
was ist richtig:

xxx.c:
1
#include "xxx.h"

xxx.h:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <inttypes.h>
4
void func(void);

oder:

xxx.c:
1
#include "xxx.h"
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <inttypes.h>

xxx.h:
1
void func(void);
Gast
ich habe in einer Headerdatei eine enum deklariert. Diese ist allerdings 
2 mal per include eingebunden, und jetzt hagelts redeclaration Fehler. 
Wie kann ich so was vermeiden?
Gast
Indem du folgendes an den anfang und ende deiner header datei schreibst:

#ifndef FILE_H_
#define FILE_H_

# Deine Sachen


#endif

Damit verhinderst du mehrfaches inkludieren desselben headers.

FILE_H_ ist im Prinzip beliebig, muss aber fuer jede header datei 
unterschiedlich sein.
Gast
>hmm danke nur jetzt kommt immer noch was von multiple definition in ner
>interrupt routine.

Haben die WinAVR-Header-Dateien nicht auch entsprechende Möglichkeiten 
der Abfrage, ob sie schin eingefügt wurden?
Das muss man halt in sämtlichen Dateien konsequent machen.
Oder Variante 3:

xxx.c:
1
//zuerst Systemheader
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <inttypes.h>
5

6
//dann eigene Header
7
#include "xxx.h"
8

9
void func( void )
10
{
11
  ...
12
}
13

14
...

xxx.h:
1
#ifndef XXX_H_INCLUDED
2
#define XXX_H_INCLUDED
3

4
void func(void);
5

6
#endif

Generell: In einem Header File sollten nur die Includes rein, die für 
dieses Header File notwendig sind. Nicht mehr.
Machst du dort einen Rundumschlag, dann drängst du dem Verwender dieses 
Include Files zusätzliche #include auf, die der vielleicht gar nicht 
haben will.

Beispiel:
Wenn ich dein xxx.h verwende
1
#include "xxx.h"
2

3
int main()
4
{
5
  foo();
6
}

dann kriege ich alleine durch den #include "xxx.h" den Header 
interrupt.h mit hinein, den ich weder benötige noch dort haben will.

Wenn jedes File, *.c oder *.h, immer nur die #include macht, die es 
tatsächlich braucht, hast du kürzest mögliche Compilezeit und auch die 
Wartung wird einfacher, weil es keine Überraschungen gibt.
Gast
Normalerweise bindest du den Header sowieso in die zugehörige C-Datei 
ein, damit die Deklarationen im Header bzw. die Definitionen in der 
C-Datei vom Compiler geprüft werden können.

Dann reicht es im Header zu inkludieren.

Beispiel xyz.c und xyz.h brauchen #include <inttypes.h>:

xyz.h:
1
#include <inttypes.h>
2

3
void func(uint8_t);

xyz.c:
1
//zuerst Systemheader
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4

5
//dann eigene Header
6
#include "xyz.h"
7

8

9
void func(uint8_t x)
10
{
11

12

13
}
Gast
Ok also alles was in c und h gebraucht wird in den Header includen.

Und wo ist jetzt der Unterschied zwischen:
#ifndef FILE_H_
#define FILE_H_

und

#ifndef XXX_H_INCLUDED
#define XXX_H_INCLUDED
Gast
Garkeiner, die Funktion ist die selbe. FILE_H_ und XXX_H_INCLUDED sind 
lediglich Präprozessor-Symbole, auf deren Nicht-Existenz mit #ifndef 
geprüft wird. Ist das Symbol nicht definiert, wird es mit #define 
definiert und alles bis zum #endif in die aufrufende Datei inkludiert.

Damit ist das Symbol in der aufrufenden Datei deklariert und der 
inkludierte Header kann in derserlben datei nicht nocheinmal inkludiert 
werden (dein ursprüngliches problem).

Du kannst diesen Symbolen im Prinzip beliebige Namen geben. Nur muss in 
jeder Header-Datei ein anderer Name verwendet werden (vgl. obige 
Ausführung). Üblicherweise konstruiert man daher den Namen aus dem 
Dateinamen des Headers unter benutzung der erlaubten Zeichen. Du musst 
darauf Achten, dass der Name möglichst einzigartig ist, da er sonst mit 
in anderen Headern definierten Symbolen oder Makros in Konflikt graten 
kann.

Beispiel:

xyz.h:
1
#ifndef XYZ_H_
2
#define XYZ_H_
3

4
void func(void)
5
#endif

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.