Folgendes Szenario: Es sei die folgende Verzeichnisstruktur gegeben: ./include |-> first.h |-> second.h ./src |-> code.c Der Quellcode code.c bindet die Datei first.h ein, diese Datei wiederum bindet die Datei second.h ein. Der Quellcode wird im Verzeichnis ./src mit dem Befehl "gcc -I. -I../include" usw. uebersetzt - das funktioniert wie erwartet. Nun arbeitet jemand am Quellcode und macht eine lokale Kopie der Datei second.h, um dort z.B. ein weiteres Makro zu definieren. Die Verzeichnisstruktur sieht dann wie folgt aus: ./include |-> first.h |-> second.h ./src |-> code.c |-> second.h Die Frage ist nun, welche Datei second.h wird letztendlich verwendet, wenn der Code im Verzeichnis ./src wiederum mit dem Befehl "gcc -I. -I../include" usw. uebersetzt wird. Ich haette eigentlich erwartet, dass es die lokale Datei second.h ist, die eingebunden wird. Dem ist allerdings nicht so, wie auch die von gcc ausgegebenen Abhaengigkeiten zeigen: code.o: code.c ../include/first.h ../include/second.h Meine Compilierung schlaegt daher fehl, da meine Aenderungen in der lokalen second.h in ./src nicht bekannt sind. Lasse ich mir Abhaengigkeiten mit makedepend generieren, so verhaelt es sich anders: code.o: code.c ../include/first.h second.h Damit ist zwar dann die Abhaengigkeit wie ich sie erwartet haette, aber das Compilieren schlaegt natuerlich nachwievor fehl, da dort ja der Preprocessor zum Einsatz kommt und die "falsche" Datei einbindet. Wenn ich ebenfalls eine lokale Kopie von first.h in ./src anlege, dann wiederum funktioniert die Sache. Ich verstehe also, was passiert und wie der Preprocessor die -I Optionen handhabt: er scheint beim Einbinden von Header Dateien in anderen Header Dateien nicht wieder alle Verzeichnisse, die ueber -I spezifiziert sind, durchzugehen. Das finde ich etwas seltsam. Die Frage ist nun: Bug oder Feature? Bzw. wer handhabt die Sache korrekt, der Preprocessor oder makedepend? Gruesse, Thomas PS: System ist opensuse 10.3 mit gcc 4.2.1 und makedepend aus xorg-x11-util-devel 7.2. -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Moin, On Sat, 25 Oct 2008, 14:25:24 +0200, Thomas Hertweck wrote:
Folgendes Szenario:
Es sei die folgende Verzeichnisstruktur gegeben:
./include |-> first.h |-> second.h ./src |-> code.c
Der Quellcode code.c bindet die Datei first.h ein, diese Datei wiederum bindet die Datei second.h ein. Der Quellcode wird im Verzeichnis ./src mit dem Befehl "gcc -I. -I../include" usw. uebersetzt - das funktioniert wie erwartet.
Nun arbeitet jemand am Quellcode und macht eine lokale Kopie der Datei second.h, um dort z.B. ein weiteres Makro zu definieren. Die Verzeichnisstruktur sieht dann wie folgt aus:
./include |-> first.h |-> second.h ./src |-> code.c |-> second.h
Die Frage ist nun, welche Datei second.h wird letztendlich verwendet, wenn der Code im Verzeichnis ./src wiederum mit dem Befehl "gcc -I. -I../include" usw. uebersetzt wird. Ich haette eigentlich erwartet, dass es die lokale Datei second.h ist, die eingebunden wird. Dem ist allerdings nicht so, wie auch die von gcc ausgegebenen Abhaengigkeiten zeigen:
code.o: code.c ../include/first.h ../include/second.h
Meine Compilierung schlaegt daher fehl, da meine Aenderungen in der lokalen second.h in ./src nicht bekannt sind. Lasse ich mir Abhaengigkeiten mit makedepend generieren, so verhaelt es sich anders:
code.o: code.c ../include/first.h second.h
Damit ist zwar dann die Abhaengigkeit wie ich sie erwartet haette, aber das Compilieren schlaegt natuerlich nachwievor fehl, da dort ja der Preprocessor zum Einsatz kommt und die "falsche" Datei einbindet.
Lang, lang ist's her... Wenn ich das noch richtig in Erinnerung habe,
spielt vor Allem die Art und Weise, _wie_ das File include't wird, eine
Rolle. Wenn Du's mit
#include "second.h"
ranziehst, wird -I. relativ zu dem File, aus dem die #include Anweisung
kommt betrachtet, also relativ zu "../include" ... Wenn du das Ding aber
wie ein System-Includefile betrachtet sehen willst, dann solltest Du
#include
Wenn ich ebenfalls eine lokale Kopie von first.h in ./src anlege, dann wiederum funktioniert die Sache. Ich verstehe also, was passiert und wie der Preprocessor die -I Optionen handhabt: er scheint beim Einbinden von Header Dateien in anderen Header Dateien nicht wieder alle Verzeichnisse, die ueber -I spezifiziert sind, durchzugehen. Das finde ich etwas seltsam.
Die Frage ist nun: Bug oder Feature? Bzw. wer handhabt die Sache korrekt, der Preprocessor oder makedepend?
Wie gesagt, wenn ich das noch richtig in Erinnerung habe (ist mittlerweile so groessenordnungsmaessig 12 Jahre her ;-), wuerde ich das als Feature bezeichnen; funktioniert zumindest so, wie ich's immer benutzt hatte.
Gruesse, Thomas
PS: System ist opensuse 10.3 mit gcc 4.2.1 und makedepend aus xorg-x11-util-devel 7.2.
Hmm, ich habe makedepend nie benutzt, sondern immer nur entsprechende Regeln im Makefile, die "gcc -M" selber genutzt haben. HTH, cheers. l8er manfred -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Manfred Hollstein wrote:
[...] Lang, lang ist's her... Wenn ich das noch richtig in Erinnerung habe, spielt vor Allem die Art und Weise, _wie_ das File include't wird, eine Rolle. Wenn Du's mit
#include "second.h"
ranziehst, wird -I. relativ zu dem File, aus dem die #include Anweisung kommt betrachtet, also relativ zu "../include" ... Wenn du das Ding aber wie ein System-Includefile betrachtet sehen willst, dann solltest Du
#include
benutzen. Zumindest findet ein "gcc -M -I. -I../include code.c" dann bei mir auch das second.h aus ./src und nicht aus ../include .
Hmm, ist das nicht genau umgekehrt zu dem was Philipp geschrieben hat? Ich binde eigentlich all meine eigenen Header mit "..." und nicht mit <...> ein. Ich dachte, Header, die mit <...> eingebunden werden, werden in den Standardverzeichnissen gesucht, waehrend "..." fuer lokale Header ist.
[...]
Hmm, ich habe makedepend nie benutzt, sondern immer nur entsprechende Regeln im Makefile, die "gcc -M" selber genutzt haben.
Ich lasse Abhaengigkeiten normalerweise direkt beim Compilieren als Nebenprodukt miterstellen. makedepend hatte ich nur als Alternative ausprobiert, um das Problem besser zu verstehen. Thanks, Thomas -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
code.o: code.c ../include/first.h ../include/second.h
Meine Compilierung schlaegt daher fehl, da meine Aenderungen in der lokalen second.h in ./src nicht bekannt sind.
Es kommt darauf an, wie Du den Header einbindest. Wenn Du ihn mit
"second.h" einbindest, sollte zuerst der im lokalen Verzeichnis
verwendet werden, während
Lasse ich mir Abhaengigkeiten mit makedepend generieren, so verhaelt es sich anders:
Makedepend verwendet man nicht, wenn schon dann gccmakedep. Makedepend macht zuviel Unsinn, als das man es vernünftig einsetzen könnte. Philipp -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Philipp Thomas wrote:
code.o: code.c ../include/first.h ../include/second.h
Meine Compilierung schlaegt daher fehl, da meine Aenderungen in der lokalen second.h in ./src nicht bekannt sind.
Es kommt darauf an, wie Du den Header einbindest. Wenn Du ihn mit "second.h" einbindest, sollte zuerst der im lokalen Verzeichnis verwendet werden, während
ihn ignorieren würde.
Hier liegst Du leider daneben. Beide Header Dateien werden jeweils ueber "name.h" eingebunden. Dennoch sieht der Praeprozessor nicht die lokale second.h, sondern die in ../include. Genau das ist es, was mich etwas verwirrt, da ich das nicht erwartet haette.
Lasse ich mir Abhaengigkeiten mit makedepend generieren, so verhaelt es sich anders:
Makedepend verwendet man nicht, wenn schon dann gccmakedep. Makedepend macht zuviel Unsinn, als das man es vernünftig einsetzen könnte.
Normalerweise lasse ich Abhaengigkeiten direkt beim Compilieren, quasi als Nebenprodukt, erstellen. makedepend habe ich nur als Alternative versucht, um herauszufinden, was vorgeht. gccmakedep kannte ich nicht - das macht aber anscheinend eh nichts anderes als gcc -M aufzurufen; daher entspricht das Resultat hier dem gleichen wie Abhaengigkeiten direkt mit dem Praeprozessor bzw. beim Compilieren zu generieren. Allerdings eben nicht dem Resultat, das ich erwartet haette. Gruesse aus London, Thomas -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
On Sun, 26 Oct 2008 10:33:11 +0000, you wrote:
Hier liegst Du leider daneben. Beide Header Dateien werden jeweils ueber "name.h" eingebunden. Dennoch sieht der Praeprozessor nicht die lokale second.h, sondern die in ../include. Genau das ist es, was mich etwas verwirrt, da ich das nicht erwartet haette.
Hmm, der ISO-C Standard lässt an der Stelle auch zu wünschen übrig: 6.10.2 Source file inclusion [...] 2 A preprocessing directive of the form # include <h-char-sequence> new-line searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined. 3 A preprocessing directive of the form # include "q-char-sequence" new-line causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read # include <h-char-sequence> new-line with the identical contained sequence (including > characters, if any) from the original directive. letztendlich ist also das Verhalten in beiden Fällen den Compiler-Bauern überlassen. In gcc-4.3.info(Preprocessor Options) finde ich zu -I- : [...] In addition, `-I-' inhibits the use of the directory of the current file directory as the first search directory for `#include "FILE"'. Was bedeuten würde, dass gcc für mit "datei" eingebundene Header zuerst das aktuelle Verzeichnis durchsuchen sollte. Wenn er das nicht tut, wäre das IMO ein Bug. Aber ich werde nächste Woche mal unsere GCC-Spezialisten befragen, mal sehen was die dazu zu sagen haben. Philipp -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Hallo! Philipp Thomas wrote:
[...]
Was bedeuten würde, dass gcc für mit "datei" eingebundene Header zuerst das aktuelle Verzeichnis durchsuchen sollte. Wenn er das nicht tut, wäre das IMO ein Bug. Aber ich werde nächste Woche mal unsere GCC-Spezialisten befragen, mal sehen was die dazu zu sagen haben.
Hat sich daraus etwas ergeben? Cheers, Thomas -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
* Thomas Hertweck (Thomas.Hertweck@web.de) [20081029 22:37]:
Hat sich daraus etwas ergeben?
Ja, wenn auch erheblich später: Wenn die Header mit "" eingebunden wurden, entscheidet die Reihenfolge, in der die zu durchsuchenden Verzeichnisse (mit -I) angegeben wurden (aktuelles Verzeichnis wird ja nicht automatisch durchsucht sondern muss mit -I. angegeben werden). Für jeden Header werden diese Verzeichnisse erneut der Reihe nach abgeklappert. Philipp -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
* Philipp Thomas [2008-11-11 19:28]:
* Thomas Hertweck (Thomas.Hertweck@web.de) [20081029 22:37]:
Hat sich daraus etwas ergeben?
Ja, wenn auch erheblich später:
Wenn die Header mit "" eingebunden wurden, entscheidet die Reihenfolge, in der die zu durchsuchenden Verzeichnisse (mit -I) angegeben wurden (aktuelles Verzeichnis wird ja nicht automatisch durchsucht sondern muss mit -I. angegeben werden).
Bei "" wird das aktuelle Verzeichnis sicher automatisch durchsucht. Gruß, Bernhard -- Bernhard Walle, SUSE Linux Products GmbH, Architecture Development -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
* Bernhard Walle (bwalle@suse.de) [20081111 19:30]:
Bei "" wird das aktuelle Verzeichnis sicher automatisch durchsucht.
Laut des Herrn Guenther nicht :) Zumindest nicht in der von Thomas angegebenen Konstallation. Philipp -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Philipp Thomas wrote:
[...]
Wenn die Header mit "" eingebunden wurden, entscheidet die Reihenfolge, in der die zu durchsuchenden Verzeichnisse (mit -I) angegeben wurden (aktuelles Verzeichnis wird ja nicht automatisch durchsucht sondern muss mit -I. angegeben werden). Für jeden Header werden diese Verzeichnisse erneut der Reihe nach abgeklappert.
Nein, werden sie ja anscheinend gerade nicht, siehe meine urspruengliche Email. Der Befehl lautete "gcc -I. -I../include" und wurde im Verzeichnis src ausgefuehrt. Die gesamte Verzeichnisstruktur ist wie folgt: ./include |-> first.h |-> second.h ./src |-> code.c |-> second.h first.h bindet second.h ueber #include "second.h" ein. GCC bindet bei diesem Beispiel die Datei second.h aus dem include Verzeichnis ein, nicht die lokale second.h im src Verzeichnis, d.h. Deine Aussage, "fuer jeden Header werden diese Verzeichnisse erneut der Reihe nach abgeklappert" ist meiner Meinung nach nicht korrekt. Sobald Du die Datei first.h von include nach src kopierst (oder einen Link first.h -> ../include/first.h im Verzeichnis src anlegst), funktioniert die Sache. Ich habe mal ein tar Archiv angehaengt, damit Du das Problem auf Deinem Rechner anschauen kannst. Ich hoffe, das tar kommt an. Entweder stimmt Deine Aussage nicht, oder ich habe sie falsch verstanden ;-) Ein "make" im src Verzeichnis schlaegt fehl, weil das Makro JJJ nicht definiert ist (obwohl in der lokalen second.h gegeben) - so verhaelt es sich jedenfalls auf meiner SuSE 10.3 (und auch auf einem Fedora 8 System). Ich war uebrigens wie Bernhard auch der Meinung, dass -I. optional ist, der GCC macht das doch normal automatisch. Spielt aber in dem Falle hier keine Rolle, denke ich, weil es ja eh explizit angegeben ist. Danke fuer Deine Hilfe, Thomas
* Thomas Hertweck [2008-11-11 20:41]:
Ich war uebrigens wie Bernhard auch der Meinung, dass -I. optional ist, der GCC macht das doch normal automatisch. Spielt aber in dem Falle hier keine Rolle, denke ich, weil es ja eh explizit angegeben ist.
-I. führt dazu dass <> auch im aktuellen Verzeichnis sucht. Aber "" sucht immer im aktuellen Verzeichnis (also dem Verzeichnis der Quellcodedatei, nicht dem Arbeitsverzeichnis des Compilers wenn du gcc z.B. als gcc -o dir/prog dir/prog.c startest also in dir/, nicht in .). Gruß, Bernhard -- Bernhard Walle, SUSE LINUX Products GmbH, Architecture Development -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Hello, On Tue, 11 Nov 2008, Bernhard Walle wrote:
* Thomas Hertweck [2008-11-11 20:41]:
Ich war uebrigens wie Bernhard auch der Meinung, dass -I. optional ist, der GCC macht das doch normal automatisch. Spielt aber in dem Falle hier keine Rolle, denke ich, weil es ja eh explizit angegeben ist.
-I. führt dazu dass <> auch im aktuellen Verzeichnis sucht. Aber "" sucht immer im aktuellen Verzeichnis (also dem Verzeichnis der Quellcodedatei, nicht dem Arbeitsverzeichnis des Compilers wenn du gcc z.B. als gcc -o dir/prog dir/prog.c startest also in dir/, nicht in .).
Und "" sucht scheinbar relativ zur aktuellen Datei. Also von 'first.h'
aus gesehen ist "second.h" in "." das in ./include.
Etwas nachvollziehbarer wird's mit 'gcc -Wp,-H'.
a) mit "second.h", beide ohne definiertes "JJJ":
$ gcc -Wp,-H -I. -I../include code.c
../include/first.h
../include/second.h
/usr/include/stdlib.h
$ gcc -Wp,-H -I../src -I. -I../include code.c
../include/first.h
../include/second.h
/usr/include/stdlib.h
b) mit
Bei Lidl gibt es nächste Woche eine CD mit "Tools für 100% PC-Sicherheit". Kann man es den Virenschreibern noch einfacher machen? -- M. Kordell Lidl verkauft Seitenschneider? -- J. Nieveler -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
David Haller wrote:
[...]
Und "" sucht scheinbar relativ zur aktuellen Datei. Also von 'first.h' aus gesehen ist "second.h" in "." das in ./include.
Was passiert, ist schon klar. Die Frage ist, ob das so richtig ist. Wie Philipp schrieb, haette ich erwartet, dass die Liste der Include Directories fuer mit "" eingebundene Header erneut durchgegangen wird statt ein zweites Header File (hier second.h) direkt im lokalen Verzeichnis des zuerst eingebundenen Header Files (hier ../include) zu verwenden. Die -I Optionen sind ja immer relativ zum Work Directory, nicht relativ zum Directory des zuerst eingebundenen Header Files. In a nutshell: GCC verhaelt sich hier schlicht nicht wie ich erwartet haette, und offensichtlich ergeht es andern genau so bzw. das Soll-Verhalten des Praeprozesors ist zumindest nicht klar spezifiziert. Gruesse aus London, Thomas -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
moin moin, Am Donnerstag, 13. November 2008 23:55 schrieb Thomas Hertweck:
Was passiert, ist schon klar. Die Frage ist, ob das so richtig ist. Wie
Die Frage(n) ist/sind vielmehr: Warum braucht man _zwei_ "second.h"? Wie sehen die headerfiles überhaupt innen aus? --- #ifndef _SECOND_H_ #define _SECOND_H_ // kram, zeugs, #endif ----- Warum kann man nicht "dir1/second.h" und "dir2/second.h" verwenden? Meines erachtens ist hier die "Organisation" Deines Prokjektes/ Codes nicht wirklich schön... *SCNR* Ciao Andre -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Andre Heine wrote:
Die Frage(n) ist/sind vielmehr:
Warum braucht man _zwei_ "second.h"?
Wie sehen die headerfiles überhaupt innen aus?
--- #ifndef _SECOND_H_ #define _SECOND_H_
// kram, zeugs,
#endif
-----
Warum kann man nicht "dir1/second.h" und "dir2/second.h" verwenden?
Meines erachtens ist hier die "Organisation" Deines Prokjektes/ Codes nicht wirklich schön...
*SCNR*
Lies doch bitte die urspruenglichen Postings durch, bevor Du Mitten in eine Diskussion einsteigst, die Du offensichtlich nicht so ganz verfolgt hast oder verstehst, denn da wurde erwaehnt, wann solch eine Situation vorkommen kann. In einem Produktionssystem kommt es sicherlich nicht vor, dass ein Header File mehrmals vorhanden ist (es sei denn, das System ist schlecht designed), wohl aber waehrend der Entwicklung von Code oder dem Arbeiten an Veraenderungen (es sei denn, Du arbeitest staendig mit einem kompletten Baum des ganzen Projekts - da wir hier aber von Tausenden von Dateien und Millionen von Codezeilen sprechen, ist das nur bedingt machbar in der Praxis). Dann hast Du z.B. systemweit installierte Header und evtl. lokale Kopien einiger Header, um Deine Aenderungen einzupflegen. Daher stellt sich durchaus die Frage, wie sich ein Praeprozessor korrekt verhalten sollte beim Einbinden der Header. Zur Beantwortung dieser Frage hast Du ja leider nicht all zu viel beigetragen. Natuerlich haben alle Header include Guards etc., es geht hier nicht um Fehler von Programmieranfaengern, sondern um ein Problem, das mitunter in der Praxis auftritt. Gruesse, Thomas -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Moinsen, Am Freitag, 14. November 2008 20:59 schrieb Thomas Hertweck: [...]
wohl aber waehrend der Entwicklung von Code oder dem Arbeiten an Veraenderungen (es sei denn, Du arbeitest staendig mit einem kompletten Baum des ganzen Projekts
Nun ja, ist auch selten bei der Entwicklung von Code, jedenfalls gab's das hier bislang noch nicht...
Zur Beantwortung dieser Frage hast Du ja leider nicht all zu viel beigetragen.
Ja, hast du wohl Recht...
Natuerlich haben alle Header include Guards etc., es geht hier nicht um Fehler von Programmieranfaengern, sondern um ein Problem, das mitunter in der Praxis auftritt.
Ein Gedanke von war unter anderem, das ggf. in beiden Header der selbe "include guard" Kram drin steht. Würde dann nicht einfach der zweite '#include "second.h"' dadurch verhindert werden? Ich auch egal, verstehe Dein Problem so oder so nicht wirklich... Entschuldigung, das ich Dich angegriffen... Andre -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Am Freitag, 14. November 2008 20:59 schrieb Thomas Hertweck:
Meines erachtens ist hier die "Organisation" Deines Prokjektes/ Codes nicht wirklich schön...
*SCNR*
Lies doch bitte die urspruenglichen Postings durch, bevor Du Mitten in eine Diskussion einsteigst, die Du offensichtlich nicht so ganz verfolgt hast oder verstehst, denn da wurde erwaehnt,
Gegeben sind:
./include/first.h
./include/second.h
./src/main.c
"first.h" bindet "second.h" ein.
"main.c" bindet "first.h" ein.
Das steht so in Deinem ersten Post?!
Der Inhalt der beiden Header:
cat first.h:
----------------
#ifndef _FIRST_
#define _FIRST_
#include "second.h"
#endif
cat second.h:
----------------
#ifndef _SECOND_
#define _SECOND_
#define MAIN "werner"
#endif
----------------
cat main.c
#include
wann solch eine Situation Aenderungen einzupflegen. Daher stellt sich durchaus die Frage, wie sich ein Praeprozessor korrekt verhalten sollte beim Einbinden der Header. Zur Beantwortung dieser Frage hast Du ja leider nicht all zu viel beigetragen. Natuerlich haben alle Header include Guards etc., es geht hier nicht um Fehler von Programmieranfaengern, sondern um ein Problem, das mitunter in der Praxis auftritt.
So so... Programmieranfaenger?! Da spricht der Doktor :-\
Gruesse, Thomas
Andre -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Andre Heine wrote:
[...]
IMHO wird nun zuerst die "first.h" eingelesen, diese liest jetzt "IHRE" "second.h"...(in include)
Da waren wir schon vor 10 Postings. Jeder weiss, was passiert.
Mein "lokaler" include wird so ignoriert, weil ja "include guards" drin stehen?
_SECOND_H existiert ja schon....
Um das geht's doch gar nicht, Du hast das Problem schlicht nicht verstanden. Es geht nicht um ein Problem, dass ein Header zwei Mal eingebunden wird - um das zu verhindern sind naemlich Include-Guards da. Es geht schlicht darum, welches File second.h eingebunden wird, und ob der Compiler die Datei einbindet, die man als User erwarten wuerde. Ich sage nein, andere sagen nein, manche sagen eventuell, nur ganz wenige sagen ja, der Praeprozessor macht genau das, was man erwarten wuerde. Go figure!
[...] So so... Programmieranfaenger?!
Da spricht der Doktor :-\
Deine Angriffe spare Dir bitte. Verstehe erst einmal das Problem, dann kannst Du vielleicht mitdiskutieren. Th. -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Hallo Thomas, ich spare mir jeglich Angriffe und entschuldige mich für jeden! Eigentlich sehe ich nur kein wirkliches Problem... Am Dienstag, 18. November 2008 10:19 schrieb Thomas Hertweck:
Andre Heine wrote:
[...]
_SECOND_H existiert ja schon....
Um das geht's doch gar nicht, Du hast das Problem schlicht nicht verstanden.
Irgendwie geht es aber doch darum. Man fragt sich, welcher Header zuerst eingebunden wird. Was willst Du denn? Aus Deinem ersten Posting entsteht doch die Frage nach der "Sortierung" der includes... Welcher Header wird denn eingebunden? Warum? Warum nicht? Und wie lassen sich beide gleichzeitig einbinden? Warum möchte man das?
Es geht nicht um ein Problem, dass ein Header zwei Mal eingebunden wird -
Das habe ich auch nicht so gemeint... Es geht darum, dass Du ein "Header" lokal duplizieren möchtest um eventuell Funktionalität in einem Modul zu überschreiben. (Der Rest soll alle so wie gehabt benutzen????) Und das "gewollt", so steht es jedenfalls in Deinem ersten Posting! Es ist nunmal kein wirklicher Normalfall. Es kommt nicht nur darauf an, welcher Header zuerst eingelesen wird, sondern auch an welcher stelle das include in der jeweiligen Datei steht. (Cross,doppelte, etc pp) Darum ist es ein Unterschied, ob nun zuerst "second.h" und anschliessend "first.h" eingebunden werden muss. Das hängt nunmal auch mit den Include Guards zusammen... Darauf wollte ich hinweisen, das ist ein Problem mit der Organisation des Buildsystemes... Der Teufel steckt nunmal im Detail... IMHO...
um das zu verhindern sind naemlich Include-Guards da.
"Include Guards" spielen hier aber eine entscheidene Rolle...
Es geht schlicht darum, welches File second.h eingebunden wird, und ob der Compiler die Datei einbindet, die man als User erwarten wuerde. Ich sage nein,
Ich sage "ja", alles funktioniert bestens mit der include Reihenfolge... Würden die Guards fehlen, gibt es ja wiederum eine Fehlermeldung wg. doppelt definierter Makros. Es hängt irgendwie alles zusammen;)
andere sagen nein, manche sagen eventuell, nur ganz wenige sagen ja, der Praeprozessor macht genau das, was man erwarten wuerde. Go figure!
[...] So so... Programmieranfaenger?!
Da spricht der Doktor :-\
Deine Angriffe spare Dir bitte. Verstehe erst einmal das Problem, dann kannst Du vielleicht mitdiskutieren.
S.o. Bitte entschuldige... Verstehe Du aber auch, das es nicht nur mit der Reihenfolge getan ist und Dein erstes Posting so einiges offen lässt... Man kommt damit nämlich sehr leicht von einem zum anderem... Friede! Andre -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
Hallo, Am Samstag, 25. Oktober 2008 schrieb Thomas Hertweck:
Folgendes Szenario:
Es sei die folgende Verzeichnisstruktur gegeben:
./include
|-> first.h |-> second.h
./src
|-> code.c
Der Quellcode code.c bindet die Datei first.h ein, diese Datei wiederum bindet die Datei second.h ein. Der Quellcode wird im Verzeichnis ./src [...]
./include
|-> first.h |-> second.h
./src
|-> code.c |-> second.h
Die Frage ist nun, welche Datei second.h wird letztendlich verwendet, wenn der Code im Verzeichnis ./src wiederum mit dem Befehl "gcc -I. -I../include" usw. uebersetzt wird. Ich haette eigentlich erwartet, dass es die lokale Datei second.h ist, die eingebunden wird. Dem ist allerdings nicht so, wie auch die von gcc ausgegebenen Abhaengigkeiten zeigen:
code.o: code.c ../include/first.h ../include/second.h
Wenn Du second.h mit #include "second.h" IN DER first.h einbindest, dann sieht gcc vermutlich das Verzeichnis ../include als aktuelles Verzeichnis - und dann ist es doch evtl. richtig, die Datei eben aus genau diesem Verzeichnis einzubinden. Das hat dann nichts mit den Compileroptionen zu tun, sondern einfach damit, dass die äußere Datei (also first.h) einfach auch in diesem Verzeichnis ist. [...]
Wenn ich ebenfalls eine lokale Kopie von first.h in ./src anlege, dann wiederum funktioniert die Sache. Ich verstehe also, was passiert und wie der Preprocessor die -I Optionen handhabt: er scheint beim Einbinden von
Genau das ist ja dann die Wirkung: wenn Du first.h eben auch im src-Verzeichnis hast, nimmt er ja dann auch die darin eingebundene second.h eben aus diesem (dann aktuelle) Verzeichnis. [...]
Die Frage ist nun: Bug oder Feature? Bzw. wer handhabt die Sache korrekt, der Preprocessor oder makedepend?
Gute Frage... Aber eigentlich finde ich das Verhalten schon ganz sinnvoll: wenn ich einen (Meta-)Header anlege, der hauptsächlich dazu dient, die vielen anderen Header einzubinden, dann will ich doch eigentlich damit auch die einzubindenden Dateien festlegen - und die sollten dann nicht davon abhängig sein, von wo aus dieser Sammelheader wiederum eingebunden wird.
Gruesse, Thomas
Gruß Martin -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org
participants (8)
-
Andre Heine
-
Bernhard Walle
-
David Haller
-
Manfred Hollstein
-
Martin Hofius
-
Philipp Thomas
-
Philipp Thomas
-
Thomas Hertweck