Enumeration und Wortlänge



  • Welche Wortlänge hat eine Enumeration? Oder ist das von der Compilereinstellung (x86, x64) abhängig? Meine Abstraktion geht nicht so weit, dass ich den Integertyp vernachlässigen möchte.

    enum File {
      FILE_A, FILE_B, FILE_C, FILE_D, FILE_E, FILE_F, FILE_G, FILE_H, FILE_NONE
    };
    

    Muss ich, um mit einer Enumeration arbeiten zu können überladene Operatoren explizit definieren?

    Beispiel:

    inline File operator+ (File x, int i) { return File(int(x) + i); }
    inline File operator+ (File x, File y) { return x + int(y); }
    inline void operator++ (File &x, int) { x = File(int(x) + 1); }
    inline void operator+= (File &x, int i) { x = File(int(x) + i); }
    inline File operator- (File x, int i) { return File(int(x) - i); }
    inline void operator-- (File &x, int) { x = File(int(x) - 1); }
    inline void operator-= (File &x, int i) { x = File(int(x) - i); }
    

    Was bietet mir eine Enumeration für Vorteile? Werden damit Fehler vom Compiler erkannt (0 <= File <= 7)?

    Vielen Dank für eure hilfreichen Hinweise an einen Laien !



  • Tomahawk schrieb:

    Welche Wortlänge hat eine Enumeration? Oder ist das von der Compilereinstellung (x86, x64) abhängig?

    Der enum -Typ sollte genügend gross sein, um alle darin enthaltenen Enumeratoren repräsentieren zu können.

    Tomahawk schrieb:

    Meine Abstraktion geht nicht so weit, dass ich den Integertyp vernachlässigen möchte.
    [...]
    Muss ich, um mit einer Enumeration arbeiten zu können überladene Operatoren explizit definieren?

    Du solltest dich eher fragen, warum du solche Operatoren brauchst. Ein enum ist eigentlich nicht als arithmetischer Datentyp gedacht, sonst kannst du gleich int oder sonst was nehmen. Vielmehr benutzt man enum als Aufzählungen einer kleinen Anzahl Stati, die ein Typ annehmen kann. Also sowas wie

    enum Farbe
    {
        Rot,
        Pink,
        Tuerkis,
    };
    

    Der eigentliche integrale Wert dahinter sollte im Normalfall nicht interessieren.



  • Ok, also ist es eher ungeeignet um einen Datentyp einzuführen und mit diesem dann im Stile eines Integers zu rechnen.

    Wenn das so ist, dann kann ich Enumerationen für meine Zwecke vergessen. Hier wird nämlich nur gerechnet.

    THX



  • Tomahawk schrieb:

    Ok, also ist es eher ungeeignet um einen Datentyp einzuführen und mit diesem dann im Stile eines Integers zu rechnen.

    Ja, sehr sogar.

    Tomahawk schrieb:

    Wenn das so ist, dann kann ich Enumerationen für meine Zwecke vergessen. Hier wird nämlich nur gerechnet.

    Okay... Mich würde aber trotzdem interessieren, wie du genau auf enum kommst? Sind dir normale arithmetische Typen aus einem Grund nicht gut genug? 🙂

    Um nicht mit Magic-Numbers rechnen zu müssen, kannst du ja immer noch Konstanten des jeweiligen Typs anlegen:

    const int BlaBli = 2312;
    


  • Arithemtische Typen nicht gut genug?

    Habe etwas im Hinterkopf, das bei Enumerationen der Bereich geprüft wird und der Compiler eine Warnung ausspuckt, wenn der Bereich der Enumeration verlassen wird. Also nur eine zusätzliche Sicherheitsreserve - mehr nicht.

    Gruss



  • Tomahawk schrieb:

    Habe etwas im Hinterkopf, das bei Enumerationen der Bereich geprüft wird und der Compiler eine Warnung ausspuckt, wenn der Bereich der Enumeration verlassen wird. Also nur eine zusätzliche Sicherheitsreserve - mehr nicht.

    Kann er gar nicht, weil du ja sowieso casten musst, um damit zu rechnen.
    Wenn du zwei File -Werte addierst, kommt ein int raus, kein File . Und einem File kannst du kein int zuweisen, ohne die daraus resultierende Fehlermeldung wegzucasten.
    Und selbst wenn, deine Operatoren werden doch erst zur Laufzeit aufgerufen - wie soll der Compiler da eine Wertüberschreitung feststellen können?



  • Registrierter Troll schrieb:

    Tomahawk schrieb:

    Habe etwas im Hinterkopf, das bei Enumerationen der Bereich geprüft wird und der Compiler eine Warnung ausspuckt, wenn der Bereich der Enumeration verlassen wird. Also nur eine zusätzliche Sicherheitsreserve - mehr nicht.

    Kann er gar nicht, weil du ja sowieso casten musst, um damit zu rechnen.
    Wenn du zwei File -Werte addierst, kommt ein int raus, kein File . Und einem File kannst du kein int zuweisen, ohne die daraus resultierende Fehlermeldung wegzucasten.
    Und selbst wenn, deine Operatoren werden doch erst zur Laufzeit aufgerufen - wie soll der Compiler da eine Wertüberschreitung feststellen können?

    Klar! Der Compiler macht auf das ungewollte Mischen von Enumeratortypen ohnes explizite Casten aufmerksam! Das wäre ein zusätzlicher Sicherheitsmechanismus für den Programmierer.



  • Tomahawk schrieb:

    Klar! Der Compiler macht auf das ungewollte Mischen von Enumeratortypen ohnes explizite Casten aufmerksam! Das wäre ein zusätzlicher Sicherheitsmechanismus für den Programmierer.

    Das trifft aber auf deine Operatoren nicht zu.

    Tomahawk schrieb:

    inline File operator+ (File x, int i) { return File(int(x) + i); }
    inline File operator+ (File x, File y) { return x + int(y); }
    inline void operator++ (File &x, int) { x = File(int(x) + 1); }
    inline void operator+= (File &x, int i) { x = File(int(x) + i); }
    inline File operator- (File x, int i) { return File(int(x) - i); }
    inline void operator-- (File &x, int) { x = File(int(x) - 1); }
    inline void operator-= (File &x, int i) { x = File(int(x) - i); }
    

    Du hast die Typsicherheit hier komplett ausgehebelt, es findet keinerlei Bereichsprüfung statt. Wenn du so eine Prüfung willst, musst du sie selbst programmieren.



  • Jetzt weiss ich auch warum Enumerationen:

    inline bitboard_t bitboard_file(const int file) {
      return bb_file[file];
    }
    
    inline bitboard_t bitboard_file(const int square) {
      return bb_file[square_file(square)];
    }
    

    Zwei unterschiedliche Funktionen, die ich NICHT überladen kann. Was mache ich nur, wenn ich doch überladen möchte???



  • Überladen im Sinne der Abstraktion ist damit erstmal Aus+Vorbei.

    inline bitboard_t file_to_bitboard(const int file) {
      return bb_file[file];
    }
    
    inline bitboard_t square_to_file_bitboard(const int square) {
      return bb_file[square_file(square)];
    }
    

    1.000.000 verschiedene Funktionsnamen....


Anmelden zum Antworten