Stilfrage: Globale Konstanten



  • Hallo zusammen,

    ich habe eine Frage zur Verwendung von globalen Konstanten, z.B. verwende ich eine Headerdatei mit folgenden Konstanten:

    //---------------------------------------------------------------------------
    #ifndef BASEUNITS_H
    #define BASEUNITS_H
    //---------------------------------------------------------------------------
    
    const int i_1KB                   = 1000;             // KiloBytes KB = 10^3
    const int i_1MB                   = 1000000;          // MegaBytes MB = 10^6
    const int i_1GB                   = 1000000000;       // GigaBytes GB = 10^9
    const __int64 i_1TB               = 1000000000000i64; // TeraBytes TB = 10^12
    
    const double d_1KB                = 1000.0;
    const double d_1MB                = 1000000.0;
    const double d_1GB                = 1000000000.0;
    const double d_1TB                = 1000000000000.0;
    
    const int i_1KiB                  = 1024;              // KibiBytes KiB = 2^10
    const int i_1MiB                  = 1048576;           // MebiBytes MiB = 2^20
    const int i_1GiB                  = 1073741824;        // GibiBytes GiB = 2^30
    const __int64 i_1TiB              = 1099511627776i64;  // TebiBytes TiB = 2^40
    
    const double d_1KiB               = 1024.0;
    const double d_1MiB               = 1048576.0;
    const double d_1GiB               = 1073741824.0;
    const double d_1TiB               = 1099511627776.0;
    
    //---------------------------------------------------------------------------
    #endif
    

    Aber da bekomme ich oft Warnungen wie:
    W8080 'd_1MB' ist deklariert, wird aber nie verwendet

    Ist das schlechter Programmierstil und wenn ja, wie werden solche Konstanten sonst deklariert und definiert ?



  • Aber da bekomme ich oft Warnungen wie:
    W8080 'd_1MB' ist deklariert, wird aber nie verwendet

    Dies kommt nur, wenn du die Variable nirgends im Code verwendet hast... Also warum musst du den Speicher denn dann belegen?



  • Naja, ich möchte die Headerdatei mit allen Konstanten in verschiedene Projekte übernehmen, verwende nicht immer alle Konstanten, möchte aber auch nicht das Rad immer wieder neu erfinden. Deshalb meine Frage. Angepasste Headerdatei für jedes Projekt nur mit den Konstanten die man braucht ?



  • #ifndef __BASEUNITS_H__
    #define __BASEUNITS_H__
    
    #define KB  (          1000  ) /* KiloBytes KB = 10^3  */
    #define MB  (       1000000  ) /* MegaBytes MB = 10^6  */
    #define GB  (    1000000000  ) /* GigaBytes GB = 10^9  */
    #define TB  (1000000000000i64) /* TeraBytes TB = 10^12 */
    
    #define KiB (1 << 10) /* KibiBytes KiB = 2^10 */
    #define MiB (1 << 20) /* MebiBytes MiB = 2^20 */
    #define GiB (1 << 30) /* GibiBytes GiB = 2^30 */
    #define TiB (1 << 40) /* TebiBytes TiB = 2^40 */
    
    #endif /* __BASEUNITS_H__ */
    

    defines sind halt schon ganz nett. Es wird garantiert kein zusätzlicher Speicher benutzt und die Nachteile der Makros wird du in diesem Fall vermutlich gar nicht bemerken.
    Aus meiner Sicht brauchst du die double-Konstanten gar nicht, weil du ja, wenn nötig, die anderen casten kannst.



  • Ja, damit hast du bei mir genau ins Schwarze getroffen. Ich hatte das zuerst mit defines, dann nach vielen Hinweisen, defines mit const zu ersetzen, habe ich das geändert. Jetzt bin ich mir nicht mehr sicher was der bessere Programmierstil ist. Mit const ist beim Debuggen immer ganz nett 🙂 , aber ist diese Verwendung in C++ so richtig 😕



  • Ist beiden grauenvoll, da unnötig 😃 In der Regel kannst du globale Variablen bei gutem Design vermeiden. Und noch ein Tipp: Versuche Konstanten aus einer Datei auszulesen, dann kannst du diese ändern ohne dein Programm immer neu erstellen zu müssen.



  • Die Möglichkeit, die Anzahl Bytes eines Kilobytes zu redefinieren, scheint mir ganz ehrlich nicht sonderlich nützlich.

    Der Compiler ist hier ziemlich übereifrig; ich benutze die selbe Art von Konstanten andauernd, und bisher hat sich kein Compiler darüber beschwert. Welchen Compiler benutzt du denn?



  • 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.


Log in to reply