"error LNK2005: already defined" trotz Mehrfach-Include-Sperre?



  • EOutOfResources schrieb:

    314159265358979 schrieb:

    Benutze anstatt #define Konstanten

    Oder wenn es geht, namenlose Enumatoren (benötigen keinen Speicher im Gegensatz zu den Konstanten).

    Die Konstanten werden von jedem halbwegs normalen Compiler doch sowieso wegoptimiert.



  • ok, ich werde es berücksichtigen...
    Vielen Dank für alles!



  • EOutOfResources schrieb:

    ...(benötigen keinen Speicher im Gegensatz zu den Konstanten).

    Sondern? Wo sollten die konstanten Werte herkommen? Magie?



  • Tachyon schrieb:

    EOutOfResources schrieb:

    ...(benötigen keinen Speicher im Gegensatz zu den Konstanten).

    Sondern? Wo sollten die konstanten Werte herkommen? Magie?

    Die werden direkt aus dem Internet runtergeladen und landen im sogenannten IRAM (Internet-RAM), so dass sie im normalen RAM keinen Platz beanspruchen. Logisch, oder? 🤡



  • Tachyon schrieb:

    EOutOfResources schrieb:

    ...(benötigen keinen Speicher im Gegensatz zu den Konstanten).

    Sondern? Wo sollten die konstanten Werte herkommen? Magie?

    Ich hoffe mal, dass du wirklich keine Ahnung hast. In dem Fall:

    // Fall 1:
    const int x = 42;
    f(x);
    

    Ohne Optimierung bezeichnet x im Prinzip eine Speicherstelle, an der der Wert 42 liegt. Beim Funktionsaufruf wird diese Speicherstelle adressiert, ausgelesen und der Wert an f übergeben.

    In Assembler etwa so:

    x    dd 42             ; Doubleword mit dem Wert 42
    ...
         push x
         call f
    

    Mit Optimierung ergibt sich dagegen das gleiche wie wenn man es gleich so geschrieben hätte:

    // Fall 2:
    f(42);
    

    In dem Fall liegt die 42 direkt im Code, sie wird nicht adressiert. In Assembler:

    push 42
          call f
    

    (Mein Assembler ist extrem eingerostet, ich hoffe man kann das einigermaßen entziffern, am Prinzip ändert das nichts.)

    Das ist damit gemeint, wenn man sagt, x benötgt Speicher oder eben nicht.



  • EOutOfResources schrieb:

    😞 C++-Code gehört in .cpp- und in .hpp-Dateien! Können wir das mal in die FAQ bringen?

    Nein, weils Geschmacks- und Konventionssache ist. Als Source-Erweiterungen sind neben .cpp auch .C, .cc und .cxx durchaus üblich. Für Header ist neben .hpp auch .hxx und .h üblich. Erlaubt ist sowieso alles, ich kenne Projekte, die (pseudo)-C++ benutzen und so gruselige Dinge wie .ko oder .kst für Konstanten, .def für typedefs und Makros (*würg*) und ähnliches benutzen.



  • Bashar schrieb:

    ...In dem Fall liegt die 42 direkt im Code, sie wird nicht adressiert...

    Und weils ein RValue ist belegt es keinen Speicher? Ich meinte schon, was ich sage. Wenn der Compiler das so wie Du hier zeigst optimieren würde, dann wäre das sogar ziemlich bescheinden, weil dann an jeder Stelle an der die Konstante benutzt wird ein neues Literal im Code stehen würde. Da braucht dann quase Speicher im Quadrat.



  • Tachyon schrieb:

    Bashar schrieb:

    ...In dem Fall liegt die 42 direkt im Code, sie wird nicht adressiert...

    Und weils ein RValue ist belegt es keinen Speicher?

    Doch, aber das ist mit der Aussage gemeint.

    Ich meinte schon, was ich sage. Wenn der Compiler das so wie Du hier zeigst optimieren würde, dann wäre das sogar ziemlich bescheinden, weil dann an jeder Stelle an der die Konstante benutzt wird ein neues Literal im Code stehen würde. Da braucht dann quase Speicher im Quadrat.

    Eine globale Konstante wie hier das COLOR_FRIEND zu adressieren kostet auch jedesmal einen vollen Pointer, also kommst du damit speichertechnich nicht besser weg. Dazu kommt der Performanceverlust durch den Speicherzugriff.



  • Bashar schrieb:

    Eine globale Konstante wie hier das COLOR_FRIEND zu adressieren kostet auch jedesmal einen vollen Pointer, also kommst du damit speichertechnich nicht besser weg. Dazu kommt der Performanceverlust durch den Speicherzugriff.

    Ja, das ist ganz bestimmt praxisrelevent, und ein Grund, Konstanten zu vermeiden. 🙄
    Btw. kommt in der Realität das Gleiche raus, egal wie man es macht.



  • Tachyon schrieb:

    Bashar schrieb:

    Eine globale Konstante wie hier das COLOR_FRIEND zu adressieren kostet auch jedesmal einen vollen Pointer, also kommst du damit speichertechnich nicht besser weg. Dazu kommt der Performanceverlust durch den Speicherzugriff.

    Ja, das ist ganz bestimmt praxisrelevent, und ein Grund, Konstanten zu vermeiden. 🙄

    Ja. Nein. Weil sie in der Regel wegoptimiert werden. BTW wirkt das Augenrollen in deiner Position nicht so, wie du dir das vielleicht erhoffst.



  • Tachyon schrieb:

    Btw. kommt in der Realität das Gleiche raus, egal wie man es macht.

    Ohne Optimierung nicht...



  • EOutOfResources schrieb:

    Tachyon schrieb:

    Btw. kommt in der Realität das Gleiche raus, egal wie man es macht.

    Ohne Optimierung nicht...

    Ohne Optimierung ist es (hoffentlich) kein produktiver Code. Dann macht der Unterschied vom Speicherverbrauch auch nichts aus.



  • pumuckl schrieb:

    Ohne Optimierung ist es (hoffentlich) kein produktiver Code.

    Schön wärs 😃 Ich hab schon relativ häufig gehört, dass Leute unoptimierten Code ausliefern. Angeblich, weil sie Angst haben, der Optimierer könnte Fehler haben. Das ist natürlich vorgeschoben.



  • Bashar schrieb:

    pumuckl schrieb:

    Ohne Optimierung ist es (hoffentlich) kein produktiver Code.

    Schön wärs 😃 Ich hab schon relativ häufig gehört, dass Leute unoptimierten Code ausliefern. Angeblich, weil sie Angst haben, der Optimierer könnte Fehler haben. Das ist natürlich vorgeschoben.

    Ist mein Windows deshalb manchmal so lahm? 🤡



  • EOutOfResources schrieb:

    😞 C++-Code gehört in .cpp- und in .hpp-Dateien! Können wir das mal in die FAQ bringen?

    Wie kommst du auf die Idee, dass .h so falsch ist?
    Durchaus gängige Praxis.



  • Bashar schrieb:

    Schön wärs 😃 Ich hab schon relativ häufig gehört, dass Leute unoptimierten Code ausliefern. Angeblich, weil sie Angst haben, der Optimierer könnte Fehler haben. Das ist natürlich vorgeschoben.

    Nicht ganz, wenn es auch nicht aktuelle Compiler betreffen sollte... Es gibt Firmen die schon lange nicht mehr supportete Entwicklungsumgebungen einsetzen, wo der Optimierer tatsächlich die Ausführreihenfolge in Verherrender Weise geändert hat.

    Natürlich ist es in gewisser Weise Schuld der Firma, wenn sie auf ein "toten Pferd" sitzen bleiben...

    Das ist aber die einzige Situation wo ich von so einem Fehler weiß, und auch einen solchen Fehler bestätigen kann.



  • Weißt du da was konkretes? Compilerfehler sind ziemlich übel, und eigentlich dürfte man einen Compiler gar nicht verwenden, der sich sowas leistet. Die meisten vermeintlichen Optimierungsfehler dürften darauf zurückgehen, dass da jemand undefiniertes Verhalten auslöst.



  • Bashar schrieb:

    Weißt du da was konkretes? Compilerfehler sind ziemlich übel, und eigentlich dürfte man einen Compiler gar nicht verwenden, der sich sowas leistet. Die meisten vermeintlichen Optimierungsfehler dürften darauf zurückgehen, dass da jemand undefiniertes Verhalten auslöst.

    Ist schon etwas her, betraf Power++ 2.5 (Leider weiß ich den genauen Fall nicht mehr, ist schon ein paar Jahre her, und ich habe zum Glück nichts mehr mit der Umgebung zu tun).



  • Meines Wissens können selbst aktuelle optimierer "korrekten" code kaputt machen, selbst die CPU-Interne Branch prediction kann eigentlich funktionierenden code - meines Wissens - in einer Multithreaded Umgebung ruinieren (bzw race conditions schaffen wo vorher keine waren). Stichwort "Optimistic write". Bin mir aber nicht sicher ob euch sowas sowieso klar ist, und ihr seht eine fehlende Verwendung der entsprechenden keywords/methoden, die das unterbinden bereits als falschen code an - dann will ich nix gesagt haben.


Anmelden zum Antworten