Klasse nicht korrekt eingebunden
-
mach mal
g++ -E main.cpp. Dann wirst du verstehen, was ich meine. Und da das sehr unübersichtlich ist, speicherst du das Ergebnis in einer Datei und suchst mit deinem Lieblingseditor in welcher Zeile GLTexture definiert wird und in welcher Zeile es das erste mal benutzt wirst und dann wirst du ziemlich sicher feststellen, dass letzteres vor ersterem sein wird. Und dann kannst du nachvollziehen, warum dies so ist.
-
So ganz verstehe ich nicht, was die Ausgabe bedeutet. Das erste mal wird GLTexture.h nach dem Quelltext einer anderen Klasse erwähnt. Ich nehme mal an, diese Klasse wurde dort kompiliert. Der Kontext in dem GLTexture.h steht ist folgender:
# 6 "GLSystem/GLSystem.h" 2 # 1 "GLSystem/GLTexture.h" 1 # 7 "GLSystem/GLSystem.h" 2 # 1 "GLSystem/GLFlatObject.h" 1Was genau sagen mir die Zahlen vor und hinter dem Pfad? Und wurde hier die Klasse deklariert oder was genau bedeutet die Erwähnung?
Anschließend steht GLTexture nur noch in der Klasse GLFlatAnimObject.h, welche auch als Quelltext dargestellt ist. Also an dieser Stelle wahrscheinlich kompiliert wurde.
Ich würde jetzt fast annehmen, dass die einfache Erwähnung oben keine Deklarierung darstellt und GLTexture.h nie deklariert wird. Aber ich weiß nicht warum.

-
1. Da wurde gar nichts compiliert. Das ist die Ausgabe des Präprozessors. Das ist das was der Compiler sieht, nachdem der Präprozessor das Spaghettieknäuel deiner Header verwurstet hat. Und daran kannst du dann nachvollziehen, warum der Compiler Probleme mit deinem Code hat.
2. Die Zeilen die du da hin geschrieben hast sind so eine Art "Kommentare" des Präprozessors für den Compiler. Der soll schließlich sinnvolle Meldungen über den Ort der fehlerhaften Zeilen machen können. Da der Präprozessoroutput alles ist, was der Compiler noch sieht, muss ihm die Information über Zeilen und Dateien irgendwie zugesteckt werden. Guckst du hier, wenn dich das interessiert:
http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
-
Ok, jetzt habe ich durchgeblickt.
Der Präprozessor geht meine includes in GLSystem.h durch, in dem ja alle anderen Dateien inkludiert werden.
Hier der Abschnitt in GLSystem.h
#include "GLObject.h" #include "GLTexture.h" #include "GLFlatObject.h"Jetzt die Präprozessorausgabe dazu mit Erläuterungen von mir:
# 1 "GLSystem/GLObject.h" 1 //Es wird mit GLObject.h begonnen # 11 "GLSystem/GLObject.h" # 1 "GLSystem/GLTime.h" 1 //Dort ist GLTime.h inkludiert, also wird dies eingeschoben # 11 "GLSystem/GLTime.h" class GLTime { //etc. }; # 12 "GLSystem/GLObject.h" 2 //Es wird mit GLObject.h fortgefahren class GLObject { //etc. }; # 6 "GLSystem/GLSystem.h" 2 //Rückkehr zu GLSystem.h # 1 "GLSystem/GLTexture.h" 1 [b]//Es wird mit GLTexture.h begonnen[/b] # 7 "GLSystem/GLSystem.h" 2 [b]//Rückkehr zu GLSystem.h[/b] # 1 "GLSystem/GLFlatObject.h" 1 //Es wird mit GLFlatObject.h begonnen # 1 "/usr/include/SDL/SDL_opengl.h" 1 3 4 //Inkludierungen in GLFlatObject.h # 64 "/usr/include/SDL/SDL_opengl.h" 3 4 extern "C" { # 3103 "/usr/include/SDL/SDL_opengl.h" 3 4 # 1 "/usr/lib/gcc/i486-linux-gnu/4.4.3/include/stddef.h" 1 3 4 # 3104 "/usr/include/SDL/SDL_opengl.h" 2 3 4 # 6551 "/usr/include/SDL/SDL_opengl.h" 3 4 } # 9 "GLSystem/GLFlatObject.h" 2 //Es wird mit GLFlatObject.h fortgefahren class GLTime; class GLCam; class GLFlatObject : public GLObject { //etc. }; # 8 "GLSystem/GLSystem.h" 2 //Rückkehr zu GLSystem.hWie man sieht, wird GLTexture.h einfach übersprungen. Die einzige Möglichkeit, welche mir dafür einfällt, wäre, dass die Präprozessorabfrage gegen Mehrfacheinbindung fehlschlägt:
#ifndef GL_TEXTURE #define GL_TEXTURE #include <string> #define LINUX #ifdef LINUX #include <SDL/SDL_opengl.h> #include <SDL/SDL_image.h> #else #include <SDL_opengl.h> #include <SDL_image.h> #endif class GLTexture { //etc. }; #endifAber es gibt keine andere Klasse mit gleichem Namen. Woher sollte also GL_TEXTURE kommen?
Ich wurde jetzt nicht schlauer daraus. Hat jemand von euch eine Ahnung, wieso der Präprozessor eine Datei überspringt?
-
Das ist doch genau das was ich gesagt hab: Zirkuläre #includes. Deine Präprozessorabfrage gegen Mehrfacheinbindung schlägt nicht fehl, sie tut genau das, wofür sie gedacht ist: Sie verhindert die Mehrfacheinbindung...
-
Aber das ist die einzige Einbindung von GLTexture.h. Später in GLFlatAnimObject.h ist es, obwohl es inkludiert wird, nicht mehr erwähnt, da hat der Präprozessor es tatsächlich komplett übersprungen. Aber vor dieser Einbindung, welche ich hier gepostet habe, wurde es nicht eingebunden. Die gepostete Stelle ist die einzige Stelle, in der es in der Präprozessorausgabe auftaucht.
-
Beispiel:
A.h inkludiert gleich am Anfang B.h.
B.h braucht Dinge aus A.h und inkludiert daher wieder A.h.
A.h wird nun aber übersprungen, da es schon inkludiert wurde.
D.h. in B.h gibts kein A.h obwohl es eigentlich gebraucht wird. Erst nach B.h kommt der eigentliche Inhalt von A.h, aber dort ist es zu spät.
-
Es sieht, sofern deine Beiträge der Wahrheit entsprechen, tatsächlich nicht nach zirkulärer Einbindung aus. Wird vielleicht fälschlicherweise irgendwo ein anderes GL_TEXTURE definiert? Ich könnte mir gut vorstellen, dass dies eventuell sogar durch die OpenGL-Header selbst geschehen könnte. Nenn das Makro doch testhalber irgendwie anders, z.B. GL_TEXTURE_ABC_123_BLABLA
-
Ja, das Prinzip kenne ich. Aber GLTexture.h benötigt keine anderen Dateien aus dem Projekt und inkludiert auch keine (die inkludes von GLTexture.h stehen in meinem letzten Post, nur string, SDL_image und SDL_opengl).
Und GLTexture.h wird nur von GLFlatAnimObject.h und von GLSystem.h inkludiert.
Habs jetzt noch einmal GLTexture.h ganz ans Ende von GLSystem.h gesetzt.
Aber an dem Problem hat das nichts geändert. GLTexture.h wird nun halt erst ganz am Ende das erste mal im Präprozessor erwähnt, wird aber wieder übersprungen.
-
Tatsache. Mit GL_BLUBB hat das Programm kompiliert. Da hat mich OpenGL wohl auf den Arm genommen.
Vielen Dank SeppJ!

Und natürlich auch dir vielen Dank dot!

-
Jaja, die Makros
. Da sieht man mal wieder die Gefahren. Daher möglichst Makronamen benutzen, die ziemlich sicher niemand sonst benutzen wird. Großschreibung ist übliche Konvention, da dran sollte man sich halten, auch wenn es die möglichen Namen einschränkt. Was aber gut kommt, sind exotische Prä- oder Suffixe. Das haben sich die Open_GL Entwickler so gedacht und haben alles mit GL_ am Anfang gemacht. Du leider auch
. Was gut kommt, wenn man für sich privat entwickelt sind zum Beispiel die eigenen Initialen als Präfix. Oder eine Abkürzung des Projektnamens.Guckst du zum Beispiel hier das Problem 1 an:
http://www.boost.org/doc/libs/1_47_0/libs/preprocessor/doc/index.html
-
Was noch besser kommt:
namespace
EDIT: Oh, Makros...pööööhse
-
Ja, da meine Engine auf OpenGL basiert, hab ich sie einfach GL-Engine genannt. Mein Makrobeginn war dann halt GL_
. Bei Version Zwei (irgendwann einmal) werd ich vielleicht alles Umbenennen und andere Präfixe verwenden. 
-
Oder noch besser: Namespaces verwenden und auf Makros verzichten

-
dot schrieb:
Oder noch besser: Namespaces verwenden und auf Makros verzichten

MAch mir mal vor, wie du das bei Include-Guards machen willst.
-
#pragma once :p
Bei Includeguards braucht man natürlich Makros. Aber dabei kann man ja eine anständige Konvention verwenden, wie z.B. FILENAME_INCLUDED oder sowas...