Stilfrage: Globale Konstanten



  • HighLigerBiMBam schrieb:

    In der Regel kannst du globale Variablen bei gutem Design vermeiden.

    Wie er sie in diesem speziellen Fall vermeiden könnte ist mir schleierhaft. Er könnte sie von globalen Funktionen im Stile von std::numeric_limits zurückgeben lassen, aber das ist immer noch eine globale variable.

    HighLigerBiMBam schrieb:

    Versuche Konstanten aus einer Datei auszulesen, dann kannst du diese ändern ohne dein Programm immer neu erstellen zu müssen.

    Weisst du was: sowas nennt man dann nicht mehr Konstante sondern Variable. Während dem Programmstart den Wert von KB auszulesen finde ich völlig sinnfrei.
    Das gesamte Programm startet damit sehr langsam, Compileroptimierungen werden komplett unterdrückt und wenn eine Bibliothek eine Konfigurationsdatei benötigt ist das für mich einer der grössten Designfehler, die man machen kann.

    @Trial: Falls es dich stark stört defines einzusetzen kannst du diese eine Warnung explizit ausschalten.



  • HighLigerBiMBam schrieb:

    In der Regel kannst du globale Variablen bei gutem Design vermeiden.

    Das sind Konstanten und keine Variablen. Und ich sehe keinen Grund warum man die vermeiden sollte.

    Und noch ein Tipp: Versuche Konstanten aus einer Datei auszulesen, dann kannst du diese ändern ohne dein Programm immer neu erstellen zu müssen.

    Konstanten die sich nie ändern können (wie die Anzahl der Bytes in einem MB) aus einer Datei auslesen, ist also besser, also ein paar Byte für ein paar mickrige Konstanten zu "verschwenden". Die der Compiler übrigens eh verwerfen wird, da sie nicht gebraucht werden.

    @Trial:
    Mach deine Konstanten static , dann sollte der Compiler ruhe geben.



  • Oder wie wär's mit externen Konstanten:

    //Constants.h
    extern const int i_1KB;
    //...
    
    //Constants.cpp
    #include "Constants.h"
    const int i_1KB = 1000;
    //...
    


  • @wxSkip: Das ist aber schon verarsche oder? Wenn nicht, wozu soll DAS bitte gut sein?



  • Also Konstanten für 1.e9, size_t(1.e9) und size_t(1)<<30 halte ich für unnötig.
    Ich würde beim Lesen an d_1GB mehr Zeit verleren, fürchte ich.
    Aber wenn es denn unbedingt sein muß, mach halt.
    Aber bitte ohne extern, Makros, Laufzeit-Datei und so Sachen.



  • theliquidwave schrieb:

    @wxSkip: Das ist aber schon verarsche oder? Wenn nicht, wozu soll DAS bitte gut sein?

    Eigentlich zu nichts, außer:
    1. Die Konstanten sollten sich mal ändern (was hier höööchstwahrscheinlich nicht vorkommen wird)
    2. Der Compiler meckert nicht mehr 😉
    3. Das Programm hat mehr Zeilen und die Statistik schaut besser aus 😃



  • 4. Man kann sie nicht mehr als Template-Parameter benutzen.

    Punkt 3 lässt mich vermuten, dass du deine Berufswahl nochmal überdenken solltest. Marketing wäre eine Möglichkeit, sofern du ohne Seele auskommst.



  • Man kann das ganze auch in ein enum packen. Damit wird dann auch kein Speicher belegt. Nachteil ist, jede Konstante darf nur einmal im enum vorkommen. Du kannst aber beliebig viele enums anlegen.



  • Nick Unbekannt schrieb:

    Nachteil ist, jede Konstante darf nur einmal im enum vorkommen.

    Laut dem C++ Standard ist das erlaubt.



  • seldon schrieb:

    4. Man kann sie nicht mehr als Template-Parameter benutzen.

    Punkt 3 lässt mich vermuten, dass du deine Berufswahl nochmal überdenken solltest. Marketing wäre eine Möglichkeit, sofern du ohne Seele auskommst.

    😃 🤡



  • Weshalb enum , wenn man keinen Aufzählungstypen definieren will? Nimm einfach const für Konstanten. Wenn du keinen antiken Compiler hast, benötigen die auch keinen Speicherplatz.

    hustbaer schrieb:

    Mach deine Konstanten static , dann sollte der Compiler ruhe geben.

    Wieso das? An der Linkage ändert es nämlich nichts.



  • Nexus schrieb:

    hustbaer schrieb:

    Mach deine Konstanten static , dann sollte der Compiler ruhe geben.

    Wieso das? An der Linkage ändert es nämlich nichts.

    Haste auch wieder recht.
    Ich hab' die Warning einfach nur abgedreht, DAS wird der Grund sein warum er bei mir nicht meckert 😃



  • Nexus schrieb:

    Weshalb enum , wenn man keinen Aufzählungstypen definieren will? Nimm einfach const für Konstanten. Wenn du keinen antiken Compiler hast, benötigen die auch keinen Speicherplatz.

    Was auch nur funktioniert, wenn man keine so-Files erstellen will.

    Was mir aber noch auffällt und noch gar nicht angesprochen wurde. Wenn ich Konstanten allgemein definiere, dann will ich die unter Umständen mehrmals verwenden und dann würdest du mit dieser const-Variante im Header an die Grenzen stoßen. Da nützen dir dann auch deine inclusion guards nichts mehr.



  • Nick Unbekannt schrieb:

    Nexus schrieb:

    Weshalb enum , wenn man keinen Aufzählungstypen definieren will? Nimm einfach const für Konstanten. Wenn du keinen antiken Compiler hast, benötigen die auch keinen Speicherplatz.

    Was auch nur funktioniert, wenn man keine so-Files erstellen will.

    Was mir aber noch auffällt und noch gar nicht angesprochen wurde. Wenn ich Konstanten allgemein definiere, dann will ich die unter Umständen mehrmals verwenden und dann würdest du mit dieser const-Variante im Header an die Grenzen stoßen. Da nützen dir dann auch deine inclusion guards nichts mehr.

    Echt? Erzeugen die Speicher?



  • so-Files?

    Unter Linux werden alle Symbole exportiert. Man kann über Attribute im GCC die Sichtbarkeit einschränken, dass ist dann aber nicht mehr portabel. Und funktioniert auch nur in jüngeren Versionen, soweit ich mich entsinne.



  • volkard schrieb:

    Erzeugen die Speicher?

    Schön wärs... Leider verbrauchen sie Speicher.
    Zum Glück ist das jedoch nur der Fall, wenn man irgendwo aus Unachtsamkeit ein & vor die Konstante schreibt.

    Nick Unbekannt schrieb:

    Unter Linux werden alle Symbole exportiert.

    Bei mir nicht. Kontrolliert mit

    $ g++ -c --optimize a.cc -o a.o
    $ ld -G a.o -o liba.so
    $ nm liba.so
    000011c8 a _DYNAMIC
    00001240 a _GLOBAL_OFFSET_TABLE_
    00000188 T _Z10do_nothingv
    0000124c A __bss_start
             U __gxx_personality_v0
    0000124c A _edata
    0000124c A _end
    $ rm a.cc a.o liba.so
    


  • Woher weiß dein Linker, welche Symbole nicht benötigt werden?

    Das könnte sehr interessant dazu sein: http://gcc.gnu.org/wiki/Visibility



  • Es ist nicht der Linker, sondern der Compiler. Ohne --optimize sind alle Konstanten vorhanden.



  • Das funktioniert aber nur, wenn du irgendwie das Symbol aus der globalen Sichtbarkeit raus nimmst. Der Compiler kann keine Symbole weg optimieren, die global sichtbar sind. Ist ja auch logisch, er sieht nur das eine Objektfile.



  • Nick Unbekannt schrieb:

    Was mir aber noch auffällt und noch gar nicht angesprochen wurde. Wenn ich Konstanten allgemein definiere, dann will ich die unter Umständen mehrmals verwenden und dann würdest du mit dieser const-Variante im Header an die Grenzen stoßen. Da nützen dir dann auch deine inclusion guards nichts mehr.

    Verstehe ich grad nicht.
    Default ist für Daten internal linkage ("static"), worauf mich Nexus netterweise hingewiesen hat.
    Wieso sollte das dann ein Problem mit SOs geben?

    Und falls das wirklich ein Problem gibt sind SOs scheisse 😃

    Ne, im Ernst, das muss gehen. Das verwenden SO viele Projekte...


Anmelden zum Antworten