Forum: Mikrocontroller und Digitale Elektronik Sind Include Guards in AtmelStudio6.1 noch nötig?


von S. L. (lonci)


Lesenswert?

Hallo!

Ich habe gerade in AtmelStudio 6.1 (Simulator) mit Mehrfacheinbindungen 
experimentiert und festgestellt, dass der Compiler nicht mekert, wenn 
eine Mehrfacheinbindung vorliegt.

Datei “a.h“

struct foo
{
  int member;
};

Datei “b.h“

#include "a.h"

Datei “c.h“

#include "a.h"
#include "b.h"

In der Datei “c.h“ wurde “a.h“ über “b.h“ doppelt eingebunden.

Kann es sein, dass der Compiler (Omptimierung wurde deaktiviert) eine 
Mehrfacheinbindung automatisch erkennt und keine Fehlermeldung ausgibt?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Eine Mehrfacheinbindung ist aus Compilersicht erst einmal per se nicht
verboten.  Ob sie sinnvoll ist oder nicht, hängt ausschließlich vom
Inhalt deiner Headerdatei selbst ab; es gibt sogar Headerdateien in
der Standardbibliothek, für die Mehrfacheinbindungen explizit sinnvoll
sind (<assert.h>).

Insbesondere jedoch, wenn eine Headerdatei #define-Anweisungen
enthält, sollte sie sich gegen Mehrfacheinbindung absichern, denn
mehrere #defines führen zumindest zu einer Warnung.

Das hat mit „Atmel Studio x.y.z“ übrigens rein überhaupt nichts zu tun.

von Karl H. (kbuchegg)


Lesenswert?

S. Lonci schrieb:

> Kann es sein, das der Compiler (Omptimierung wurde deaktiviert) eine
> Mehrfacheinbindung automatisch erkennt und keine Fehlermeldung ausgibt?


Wenn schon, dann hat er eher festgestellt, dass deine Doppelte struct 
Definition in allen Punkten in beiden Fällen übereinstimmt, und deshalb 
spart er sich eine Fehlermeldung, weil ja dann ganz offensichtlich 
ohnehin nichts schlimmes passieren kann.

Aber einen #include kann der Präprozessor (der behandelt includes) nicht 
einfach ignorieren.

von Kaj (Gast)


Lesenswert?

S. Lonci schrieb:
> Kann es sein, dass der Compiler (Omptimierung wurde deaktiviert) eine
> Mehrfacheinbindung automatisch erkennt und keine Fehlermeldung ausgibt?

Ich sag mal so:
Es wird einen Grund haben, warum in einer Headerdatei (in diesem Fall: 
test_header.h), die du über Atmel Studio erzeugst drin steht:
1
#ifndef TEST_HEADER_H_
2
#define TEST_HEADER_H_
3
4
5
#endif /* TEST_HEADER_H_ */

Und der Grund ist bestimmt nicht, weil irgendeinem Programmierer 
langweilig war und er das da aus spaß reingebaut hat...
Schalte mal -Wall -Wextra -Werror ein, vielleicht sieht das dann schon 
anders aus. Und das ganze hat auch nichts mit den optimierungs 
einstellungen zu tun.

von S. L. (lonci)


Lesenswert?

Eine Frage habe ich noch zur Schreibweise:

Warum schreibt man #ifndef B_H_

und nicht #ifndef b.h ?

1
#ifndef B_H_
2
#define B_H_
3
4
#include "a.h"
5
6
#endif

von Karl H. (kbuchegg)


Lesenswert?

S. Lonci schrieb:

> und nicht #ifndef b.h ?
>

Probiers halt einfach aus, ob du in einem Preprozessor Makro einen Punkt 
im Makronamen benutzen kannst.
Denk auch drann: Ein makro ist im Reglfall ja kein Selbstzweck. Ok, der 
Fall Include Guards ist ein bischen anders gelagert, aber im Regelfall 
wird ja ein Makro auch irgendwo im Programmtext verwendet.

Machst du dir jetzt ein
1
#define TEST.X   var

und verwendest das
1
int main()
2
{
3
  int var;
4
5
  TEST.X = 5;
6
}

was wird dann wohl passieren?

Das ist zwar immer eine Gratwanderung und komplexere Sachverhalte kann 
man damit eher schlecht ergründen. Aber viele einfache Dinge kann man 
tatsächlich einfach ausprobieren und aus der Fehlermeldung des Compilers 
seine Schlüsse ziehen. Hat man mehrere Compiler zur Verfügung, dann kann 
man auch mal vergleichen, wie ein und derselbe Fehler zu 
unterschiedlichen Fehlermeldungen (im Wortlaut verschieden) führt. Das 
ist ganz hilfreich, sich da auch eine gewisse Praxis anzueignen, um aus 
Fehlermeldungen die richtigen Schlüsse zu ziehen.

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.