Forum: Compiler & IDEs Include file1.h oder file2.h


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,

ich habe zwei Header-Dateien

file1.h und
file2.h

von denen jeweils eine von mehreren C-Dateien includiert werden soll. Um 
genau zu sein: Ich habe nur eine Header-Datei. Entweder liegt file1.h 
oder file2.h in der Build-Umgebung vor.

Sollten beide vorliegen, ist es kein Problem, wenn beide, oder nur die 
erste, die gefunden wird, includiert werden.

Gibt es die Möglichkeit, dem C-Präprozessor zu sagen, er solle eine 
Header-Datei nur includieren, wenn sie vorhanden ist?

Oder er solle eine Datei includieren, aber wenn es nicht klappt, nicht 
traurig sein, und einfach weiter machen?

Viele Grüße
W.T.

von Markus F. (mfro)


Lesenswert?

Nein. Weder, noch.

Was Du machen kannst ist, dein Makefile feststellen zu lassen, ob eine 
bestimmte Datei vorhanden ist oder nicht und abhängig davon dem 
Präprozessor entsprechende defines zukommen lassen. Aber das ist 
reichlich von hinten durch die Brust ins Auge.

Es wäre vielleicht besser, erst mal das Problem zu beschreiben, das Du 
lösen willst, möglicherweise gibt's ja eine bessere Lösung.

von Wilhelm M. (wimalopaan)


Lesenswert?

Der C++-Programmierer benutzt dazu:
1
#if __has_include(<f.h>)
2
// ...
3
#endif

von Pete K. (pete77)


Lesenswert?

Ein header-File gehört immer zu einem bestimmten C-File. Insofern ist 
Deine Frage irgendwie komisch.

Stelle doch mal die beiden Files hier hinein, dass können wir Dir besser 
helfen.

Ich vermute, dass in dem headerfile mehr drin ist, als da reingehört.

von Peter D. (peda)


Lesenswert?

Walter T. schrieb:
> ich habe zwei Header-Dateien
>
> file1.h und
> file2.h

Schon das ist sehr ungebräuchlich.
Ein Filename sollte immer beschreibend sein, z.B. uart.h, hardware.h, 
remote.h usw.

von Walter T. (nicolas)


Lesenswert?

Markus F. schrieb:
> Es wäre vielleicht besser, erst mal das Problem zu beschreiben, das Du
> lösen willst, möglicherweise gibt's ja eine bessere Lösung.

Peter D. schrieb:
> Ein Filename sollte immer beschreibend sein, z.B. uart.h, hardware.h,
> remote.h usw.

Das Problem, das ich lösen will, ist, dass ich drei Header-Files habe, 
die in jedem meiner Projekte vorkommen, deren Inhalt aber schon lange 
nicht mehr dem Namen entsprechen, den ich ihnen am Anfang meines 
Schaffens gegeben habe.

Eigentlich gehört alles, was in diesen drei Header-Dateien liegt, in 
zwei Dateien, die anders heißen.

Andererseits will ich nicht in meiner kompletten Codebasis 
herumpfuschen, nur um wieder etwas ordentlicher zu werden. Dabei baue 
ich sicher wieder neue Fehler ein.

Also geht mein Bestreben dahin, die neuen Header zu nutzen, die alten 
-bis auf weiteres- aber auch noch zu unterstützen und dabei eine 
Compiler-Warnung auszugeben.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Walter T. schrieb:
> Andererseits will ich nicht in meiner kompletten Codebasis
> herumpfuschen, nur um wieder etwas ordentlicher zu werden. Dabei baue
> ich sicher wieder neue Fehler ein.

Einen Tod muss man sterben.

Räum' auf, sonst schleppst Du diese überflüssigen Altlasten auf Ewigkeit 
mit Dir herum.

Als erste Abhilfe kannst Du in die alten, falschen Dateien ein #include 
der richtigen Dateien einbauen, und eine Warnung ausgeben (wie auch 
immer das Dein Compiler handhabt, mit #pragma message, #pragma warning 
oder was auch immer).

Dann kannst Du unreparierte Bestandsprojekte weiter verwenden, bekommst 
aber einen Hinweis darauf, daß Du sie reparieren solltest.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Walter T. schrieb:
> Gibt es die Möglichkeit, dem C-Präprozessor zu sagen, er solle eine
> Header-Datei nur includieren, wenn sie vorhanden ist?

Das geht so nicht, aber was Du machen kannst, ist zwei leere Dateien mit 
dem Namen in ein Verzeichnis legen und dieses Verzeichnis dann an das 
Ende der Liste, der vom Compiler zu durchsuchende Verzeichnisse setzen. 
Dann findet der Compiler diese leere Datei, wenn er nicht schon vorher 
die "richtige" Datei gefunden hat.

von Peter D. (peda)


Lesenswert?

Torsten R. schrieb:
> Dann findet der Compiler diese leere Datei, wenn er nicht schon vorher
> die "richtige" Datei gefunden hat.

Sowas nennt man: sich gepflegt selber ins Knie schießen.
Irgendwann hat man den dirty hack vergessen und dann sucht man den 
Fehler völlig verzweifelt an der falschen Stelle.

Ich bin immer dankbar, wenn der Compiler mir Fehlermeldungen oder 
Warnungen gibt, in der Regel hat er damit auch recht.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Peter D. schrieb:

> Sowas nennt man: sich gepflegt selber ins Knie schießen.
> Irgendwann hat man den dirty hack vergessen und dann sucht man den
> Fehler völlig verzweifelt an der falschen Stelle.

Peter, der Walter hat eine Frage gestellt; ich habe Ihm eine Lösung 
angeboten. Ob er damit glücklich wird, oder nicht, wirst weder Du noch 
ich beurteilen können.

In der Realität gibt es immer wieder mal die Notwendigkeit Sachen zu 
tun, die relativ weit vom Optimium entfernt sind.

Was wäre z.B. wenn der Code, den Walter nicht refaktorieren möchte 
demnächst eh komplett ersetzt werden soll? Würdest Du ihm dazu raten, 
einige Millionen Zeilen Code erst zu refaktorieren und dann zu 
entsorgen?

Wir kennen die Hintergründe nicht, deswegen sollten wir uns auch mit 
Urteilen etwas zurück halten, auch wenn wir immer mal wieder gerne 
raushängen lassen, dass bei uns alles super ist und wir keine Leichen im 
Keller haben! ;-)

mfg Torsten

von Der Andere (Gast)


Lesenswert?

Torsten R. schrieb:
> Wir kennen die Hintergründe nicht, deswegen sollten wir uns auch mit
> Urteilen etwas zurück halten, auch wenn wir immer mal wieder gerne
> raushängen lassen, dass bei uns alles super ist und wir keine Leichen im
> Keller haben! ;-)

Richtig, aber fast jedesmal wenn man die Leichen im Keller nicht 
entsorgt ärgert man sich später drüber.
Deshalb ist der beste Rat trotzdem:

Rufus Τ. F. schrieb:
> Räum' auf, sonst schleppst Du diese überflüssigen Altlasten auf Ewigkeit
> mit Dir herum.

Und ja auch ich habe beschissenen Code den ich nicht "refactored" habe, 
obwohl es sinnvoll wäre :-)

von Peter D. (peda)


Lesenswert?

Torsten R. schrieb:
> Peter, der Walter hat eine Frage gestellt; ich habe Ihm eine Lösung
> angeboten.

Und ich habe nur auf die Gefahren hingewiesen, die darin lauern. Man 
kann nicht davon ausgehen, daß die jeder selber erkennt.
Es war nicht als persönliche Kritik gemeint.

von Wilhelm M. (wimalopaan)


Lesenswert?

Torsten R. schrieb:
> Peter D. schrieb:
>
>> Sowas nennt man: sich gepflegt selber ins Knie schießen.
>> Irgendwann hat man den dirty hack vergessen und dann sucht man den
>> Fehler völlig verzweifelt an der falschen Stelle.
>
> Peter, der Walter hat eine Frage gestellt; ich habe Ihm eine Lösung
> angeboten. Ob er damit glücklich wird, oder nicht, wirst weder Du noch
> ich beurteilen können.

Wahrscheinlich kann er auch einfach seine C-Datei (bedeutet das jetzt, 
dass sie abc.C oder abc.c heißt oder das dort C-Code enthalten ist) mit 
einem C++-Compiler übersetzen und dann das Konstrukt verwenden, was ich 
oben geschrieben habe ;-)

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Wilhelm M. schrieb:

> Wahrscheinlich kann er auch einfach seine C-Datei (bedeutet das jetzt,
> dass sie abc.C oder abc.c heißt oder das dort C-Code enthalten ist) mit
> einem C++-Compiler übersetzen und dann das Konstrukt verwenden, was ich
> oben geschrieben habe ;-)

Nur, dass das kein C++ ist, sondern eine Erweiterung von clang...

von Wilhelm M. (wimalopaan)


Lesenswert?


: Bearbeitet durch User
von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Wilhelm M. schrieb:

> Wahrscheinlich kann er auch einfach seine C-Datei (bedeutet das jetzt,
> dass sie abc.C oder abc.c heißt oder das dort C-Code enthalten ist) mit
> einem C++-Compiler übersetzen und dann das Konstrukt verwenden, was ich
> oben geschrieben habe ;-)

Ausserdem war es Walters Ziel, den Code nicht anzufassen. Wenn er 
überall dieses bedingte include einfügt, dann kann er auch dort den 
neuen Dateinamen einsetzen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Das kann ich in der Ursprungsfrage nicht entdecken ...

Dies war die Frage:

> Gibt es die Möglichkeit, dem C-Präprozessor zu sagen, er solle eine
> Header-Datei nur includieren, wenn sie vorhanden ist?
>
> Oder er solle eine Datei includieren, aber wenn es nicht klappt, nicht
> traurig sein, und einfach weiter machen?

von Peter D. (peda)


Lesenswert?

Es ist sinnvoll, sich zentrale Bibliotheken anzulegen. Nur sind die in 
der Regel nicht ausgereift, es fallen einem immer wieder noch 
Erweiterungen und Verbesserungen ein oder auch Bugs sind zu beheben.
Daher kopiere ich den gerade aktuellen Stand in das jeweilige Projekt. 
Wenn man sie nämlich zentral benutzt, hat man das Problem, daß alte 
Projekte plötzlich nicht mehr laufen, wenn man sie wieder anfassen muß.
Mit der lokalen Kopie kann man die Lib pflegen ohne Rücksicht auf die 
heilige Kuh der Rückwärtskompatibilität. Und man muß keine Verrenkungen 
mit Macros und Filenamen machen, die den Code unübersichtlich und 
fehlerträchtig machen.
Ich habe schon zu oft Zeit vergeuden müssen, weil eine Lib geändert 
wurde und der alte Stand für das Projekt nicht oder nur schwer zu 
restaurieren war.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Wilhelm M. schrieb:
> Das kann ich in der Ursprungsfrage nicht entdecken ...


> Eigentlich gehört alles, was in diesen drei Header-Dateien liegt, in
> zwei Dateien, die anders heißen.

> Andererseits will ich nicht in meiner kompletten Codebasis
> herumpfuschen, nur um wieder etwas ordentlicher zu werden. Dabei baue
> ich sicher wieder neue Fehler ein.

von Wilhelm M. (wimalopaan)


Lesenswert?

Torsten R. schrieb:
> Wilhelm M. schrieb:
>> Das kann ich in der Ursprungsfrage nicht entdecken ...
>
>
>> Eigentlich gehört alles, was in diesen drei Header-Dateien liegt, in
>> zwei Dateien, die anders heißen.
>
>> Andererseits will ich nicht in meiner kompletten Codebasis
>> herumpfuschen, nur um wieder etwas ordentlicher zu werden. Dabei baue
>> ich sicher wieder neue Fehler ein.

Das kam erst später zur der Ursprungsfrage dazu!

Und trotzdem könnte er genau das mit dem Ansatz machen ... unter der 
Voraussetzung, dass sein C-Code keine C-Erweiterungen (__flash, etc.) 
enthält oder bspw. type-punning über union-member macht ...

von W.S. (Gast)


Lesenswert?

Walter T. schrieb:
> Oder er solle eine Datei includieren, aber wenn es nicht klappt, nicht
> traurig sein, und einfach weiter machen?

Walter, du bist mal wieder völlig unlogisch.

Also:
a) Wenn in der .h irgend etwas wichtiges drinsteht, das dein Code 
tatsächlich braucht, dann MUSS diese .h gefunden und eingebunden werden. 
Sonst bricht die Übersetzung mit nem Fehler eben ab - eben weil was 
Wichtiges fehlt.

b) Wenn der Compiler nach deinem Wunsche die nicht vorhandene .h 
ignoriert und einfach weitermacht, dann bricht er ohnehin die 
Übersetzung wegen Fehler ab.

c) Wenn der Compiler ebenfalls nach deinem Wunsche die nicht vorhandene 
.h ignoriert - und es ergeben sich daraus KEINE Fehler, dann ist diese 
.h offensichtlich völlig überflüssig.

d) es gibt noch nen Sonderfall: Wenn du Tanz auf dem Drahtseil machst, 
indem du extensiv mit
#ifndef xyz..

arbeitest, und dabei im Falle der fehlenden .h die dortigen Inhalte 
anderweitig ersetzt, dann erzeugst du einen derart miserabel wartbaren 
Code, daß du dir früher oder später daran den Hals brichst. Also laß 
sowas lieber sein.

Kurzum: Fragen dieser Art kommen nur durch einen unüberlegten 
Gesamtentwurf  zustande. Also befolge lieber den Rat von Rufus und räume 
auf.

Nochwas: ne .h sollte wirklich nur soviel enthalten, wie unbedingt für 
das Benutzen des Inhaltes der .c von außen nötig ist. Viele auch 
kommerzielle Hersteller ignorieren das.

W.S.

von A. S. (Gast)


Lesenswert?

Walter, es fehlt irgendwie noch Info.

Die neuen kannst Du doch sofort verwenden.

Die alten können doch sofort warnungen werfen,
- wenn Du #warning da reinschreibst.
- oder wenn Du deren Include-Guard auswertest.

Du kannst dabei auch die alten Header entkernen und darin ein #include 
der neuen setzen.

Du kannst dort, wo headerX.h fehlt, einfach eine leere Datei hinlegen.

Wenn Du die Suchpfad-Reihenfolge kennst (diese fest ist), kannst Du 
wahlweise die leere Datei an den Anfang oder ans Ende setzen, je 
nachdem, was Du erreichen willst.


Mache mal ein entsprechendes Beispiel mit 2 alten Headern, einer neuen. 
Jeweils #include-Guards und eine "Problem-Definition". Und dann dazu die 
entsprechenden alten und neuen include-Zeilen im C-File.

von Eric B. (beric)


Lesenswert?

Hört sich für mich an nach einem Problem das man besser mit vernünftige 
Versionsverwaltung angehen könnte: svn, git, ... you name it.

Walter T. schrieb:
> Eigentlich gehört alles, was in diesen drei Header-Dateien liegt, in
> zwei Dateien, die anders heißen.

Wo liegt dann das Problem? Die alte Dateiten werden von alten, 
bestehenden Code benutzt. Für neue Projekte legst du die zwei, 
anders-heißende neue Header-Dateien an und includierst die. Käse fertig.

(Mit eine Versionsverwaltung kannst du dann einen Baseline für die alte 
Projekte anlegen, danach die alte Headers löschen und dich freuen, dass 
der alte Kram nicht mehr deiner jetztigen Code-Base verseucht;-))

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.