Verschiedene Compilererror



  • Scorcher24 schrieb:

    1.) #pragma once ist Visual Studio spezifisch

    Nein.

    Scorcher24 schrieb:

    Vielleicht in dem Fall nicht so schlimm, ich mags trotzdem nicht. Nutze include-guards.

    Wenn man nicht alle Compiler unterstützen will, kann man das ruhig machen, auch wenn du es nicht magst. Man muss sich nämlich keine Makros ausdenken und gegebenenfalls ändern, hat weniger zu schreiben und der Präprozessorvorgang läuft möglicherweise schneller ab. Auch wenn das keine enormen Vorteile sind.

    Viel schlimmer finde ich z.B., dass alles inline ist, dass merkwürdige Operatoren wie / auf Vektoren definiert werden, dass Code nicht wiederverwendet wird und dass durch Zeiger-Umbiegen undefiniertes Verhalten entsteht. Der Grund für solchen Code besteht wahrscheinlich in diversen Performancemythen.



  • Nexus schrieb:

    Scorcher24 schrieb:

    Vielleicht in dem Fall nicht so schlimm, ich mags trotzdem nicht. Nutze include-guards.

    Wenn man nicht alle Compiler unterstützen will, kann man das ruhig machen, auch wenn du es nicht magst. Man muss sich nämlich keine Makros ausdenken und gegebenenfalls ändern, hat weniger zu schreiben und der Präprozessorvorgang läuft möglicherweise schneller ab. Auch wenn das keine enormen Vorteile sind.

    Wenn man beide Vorteile will, dann macht man eben beides. Wenn der Compiler das pragma nicht unterstützt (ursprünglich war es afaik nur VS-spezifisch), dann wird es einfach ignoriert und die include guards greifen.
    Makros denke ich mir nie selber aus. Die werden von einem kleinen Addin, dass ich für VS gemacht habe automatisch generiert (wie auch das ganze Standard Zeugs, wie include guards und passende .cpp), wenn ich eine Datei (.h) anlege.



  • drakon schrieb:

    Wenn man beide Vorteile will, dann macht man eben beides.

    Das hingegen vereint wirklich nur Nachteile, es sei denn, man ist auf die Präprozessorgeschwindigkeit angewiesen. Ansonsten gibt es mehr zu schreiben, mit Dateinamen konsistent zu halten, und auf anderen Compilern hat man lästige Warnungen (es sei denn, man führt noch weitere #ifdef s ein, was aber definitiv hässlich wird).



  • Also Headerguards selbst zu schreiben ist unsinnig. Die kann man sich schön generieren lassen und dann mit einem Zeitstempel drin und man hat nie Probleme mit Konsistenz (wer zwingt denn einen den mit dem Dateinamen zu identifizieren? Projektname und Zeitstempel sollten ausreichend sein). Und dass es Warnungen gibt wüsste ich jetzt nicht und wenn schon kann man, wenn die einen stören ja bestimmt irgendwo ausschalten. Und selbst wenn nicht habe ich lieber ein paar Warnungen, als etwas, dass nicht kompiliert.

    Ob ich jetzt mit oder ohne Headguards/pragma die Dateien erzeuge spielt für mich keine Rolle, aber funktionieren tut es dann überall und dort, wo es geht auch noch ein wenig schneller.

    Aber ich weiss auch nicht, warum wir hier über solchen Nonsens diskutieren müssen.



  • drakon schrieb:

    Also Headerguards selbst zu schreiben ist unsinnig.

    Wäre dies so, würden das nicht etliche C++-Bibliotheken tun.

    drakon schrieb:

    Aber ich weiss auch nicht, warum wir hier über solchen Nonsens diskutieren müssen.

    Ich hab Scorcher24 lediglich darauf hingewiesen, dass #pragma once manchmal gerechtfertigt sei. Es hat dich niemand gezwungen, darauf zu antworten.



  • Nexus schrieb:

    drakon schrieb:

    Also Headerguards selbst zu schreiben ist unsinnig.

    Wäre dies so, würden das nicht etliche C++-Bibliotheken tun.

    Woher weisst du wie die ihre Headerguards erstellen?

    Nexus schrieb:

    drakon schrieb:

    Aber ich weiss auch nicht, warum wir hier über solchen Nonsens diskutieren müssen.

    Ich hab Scorcher24 lediglich darauf hingewiesen, dass #pragma once manchmal gerechtfertigt sei. Es hat dich niemand gezwungen, darauf zu antworten.

    Ich habe ergänzt, dass man beides machen kann und du hast gesagt, dass es nur Nachteile hat und dann lediglich Tipparbeit und Warnungen genannt und dass das keine wirklichen Punkte sind habe ich ja bereits gesagt.

    Ob die Vorteile(kompiliert überall und dort wo es geht auch noch schneller) die Nachteile(ev. (abschaltbare) Warnungen) überwiegen muss jeder selbst entscheiden. Die einzelnen Versionen haben jeweils Nachteile, welche die vereinte Variante nicht hat (kompiliert nicht überall, resp. langsamer).



  • drakon schrieb:

    Woher weisst du wie die ihre Headerguards erstellen?

    Sie enthalten zumindest keine Timestamps und sind semantisch nach den Inhalten der Datei benannt. Ob gar kein Tool verwendet wird, oder ein Snippet, zu dem man nur noch den Makro-Namen eingibt o.Ä., kann ich nicht sagen.

    drakon schrieb:

    Ich habe ergänzt, dass man beides machen kann und du hast gesagt, dass es nur Nachteile hat

    ...sofern man nicht auf den Geschwindigkeitsgewinn durch #pragma once angewiesen ist.

    drakon schrieb:

    und dann lediglich Tipparbeit und Warnungen genannt und dass das keine wirklichen Punkte sind habe ich ja bereits gesagt.

    Ja, die Unwichtigkeit habe sogar ich schon mit "Auch wenn das keine enormen Vorteile sind" im ersten Post angedeutet. 😉

    Aber stimmt schon, gross zu diskutieren lohnt sich nicht. Zumal wir das wahrscheinlich recht ähnlich sehen, aber wohl ein wenig aneinander vorbeigeredet haben...



  • Danke, das war der Grund! Da war nur noch ein Problem: In der Klasse habe ich inline einen Operator /= definiert, jetzt habe ich den Operator nur in der Klasse icMatrix deklariert und ihn in icMatrix.cpp definiert, sprich:

    icMatrix& operator/= (const icMatrix& a);
    

    und

    icMatrix::operator/= (const icMatrix& a)
    {
    	return *this *= icMatrixInvert(a);
    }
    

    Beim erstellen kommen (zum Glück) nur noch 3 Fehler und eine Warnung:

    1>------ Erstellen gestartet: Projekt: IonCore, Konfiguration: Debug Win32 ------
    1>Kompilieren...
    1>icMatrix.cpp
    1>d:\spieleprogrammierung\ioncore\src\icmatrix.cpp(23) : error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    1>d:\spieleprogrammierung\ioncore\src\icmatrix.cpp(23) : error C2556: 'int icMatrix::operator /=(const icMatrix &)': Überladene Funktion unterscheidet sich nur hinsichtlich des Rückgabetyps von 'icMatrix &icMatrix::operator /=(const icMatrix &)'
    1>        d:\spieleprogrammierung\ioncore\include\icmatrix.h(140): Siehe Deklaration von 'icMatrix::operator /='
    1>d:\spieleprogrammierung\ioncore\src\icmatrix.cpp(23) : error C2040: 'icMatrix::operator /=': 'int (const icMatrix &)' unterscheidet sich von 'icMatrix &(const icMatrix &)' in Bezug auf die Anzahl vorgenommener Dereferenzierungen
    1>d:\spieleprogrammierung\ioncore\src\icmatrix.cpp(175) : warning C4244: 'Argument': Konvertierung von 'double' in 'float', möglicher Datenverlust
    1>Das Buildprotokoll wurde unter "file://d:\Spieleprogrammierung\IonCore\Debug\BuildLog.htm" gespeichert.
    1>IonCore - 3 Fehler, 1 Warnung(en)
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
    

    Alle Fehler verweisen direkt auf die Definition des Operators /= und das Warning auf

    const float s = (float) (1.0 / tanf(FOV * 0.5));
    

    in der Funktion icMatrixProjection . Vielleicht könnt ihr mich ein bisschen über diese Fehler aufklären, den ersten habe ich nämlich ungewöhnlich oft und ich weiß nicht, was das Problem ist. Zwar habe ich mich darüber informiert, aber ich sehe den Fehler nicht.



  • Ok, ich habe jetzt noch einiges selber gelöst. Ich darf ja nicht einfach

    icMatrix::operator/= (const icMatrix& a)
    {
        return *this *= icMatrixInvert(a);
    }
    

    schreiben, sondern muss flogendes schreiben:

    icMatrix& icMatrix::operator/= (const icMatrix& a)
    {
    	return *this *= icMatrixInvert(a);
    }
    

    Kein Wunder, warum die Fehler kamen. Nun bleibt nur noch die Warnung, ist diese brechtigt? Oder wie soll ich mit ihr umgehen? Ignorieren?



  • Irgendwer schrieb:

    Nun bleibt nur noch die Warnung, ist diese brechtigt? Oder wie soll ich mit ihr umgehen? Ignorieren?

    Warnungen sind immer berechtigt. Float hat eine geringere Genauigkeit als double. Warum auch immer du float benutzt, der Compiler merkt, dass du an einer Stelle einen double stillschweigend in einen float konvertierst und warnt dich vor eben dem Genauigkeitsverlust.
    Mal abgesehn von der Tatsache, dass es wirklich keinen Sinn macht, mit deinen Kenntnissen schon sowas komplexes wie eine Spiele-Engine anzufangen (da kommt nur Murks raus, da du offensichtlich die nötige Erfahrung nicht besitzt), schau dir mal im Magazin den Artikel zur Operatorüberladung an. Nachdem du den Ratschlag, keine unintuitiven Operatoren anzubieten, beherzigt und die Häfte deiner Operatoren wieder rausgenommen hast, bleibt immernoch einiges zu tun.


Anmelden zum Antworten