enum statt #define?



  • Hallo zusammen,

    Bei einigen C-Frameworks ist mir aufgefallen, dass zusammengehörige Konstanten über den Präprozessor definiert werden. Beispiele dafür sind GL_COLOR_BUFFER_BIT in OpenGL oder VK_RETURN in der WinAPI.

    Was ist der Grund, dass man hier auf Typsicherheit verzichtet? Mir ist bewusst, dass Typsicherheit in C nicht erste Priorität hat, aber in diesem Falle würde man ja nichts verlieren, oder?



  • enum sollte man wenn immer möglich gegenüber #define immer bevorzugen. Leider wissen das viele Programmierer nicht. Gerade die WinAPI ist wohl das beste Antibeispiel für Codedesign und C Programmierstil.



  • enum macht den code hässlicher und was bringt es mir mehr als #define? nix. ist also ähnlich wie der ganze cpp crap, da sehen wir es eben auch nicht ein static_cast<idioten>(sicher) zu schreiben als einfach den normalen c cast.



  • checker_ schrieb:

    enum macht den code hässlicher und was bringt es mir mehr als #define? nix.

    nö, enum ist besser. erstmal greift dabei die typüberprüfung des compilers und zweitens siehst du beim debuggen die namen der konstanten und nicht einfach nur irgendwelche zahlen.
    🙂



  • Danke für die Antworten!

    rüdiger schrieb:

    enum sollte man wenn immer möglich gegenüber #define immer bevorzugen. Leider wissen das viele Programmierer nicht.

    Sowas habe ich eben auch gedacht. Aber dass es auch sonst schon paar Mal gesehen habe, hat mich etwas verunsichert. Gut, dass enum auch in C bevorzugt wird... 🙂

    +fricky schrieb:

    nö, enum ist besser. erstmal greift dabei die typüberprüfung des compilers und zweitens siehst du beim debuggen die namen der konstanten und nicht einfach nur irgendwelche zahlen.

    Stimmt, an das Debugging habe ich jetzt gar nicht gedacht. Das kommt noch dazu.

    checker_ schrieb:

    ist also ähnlich wie der ganze cpp crap, da sehen wir es eben auch nicht ein static_cast<idioten>(sicher) zu schreiben als einfach den normalen c cast.

    Sagen wir, du siehst es nicht ein. Würdest du C++ ein wenig kennen, sähe das vielleicht anders aus.



  • In C stellt eine enum-Aufzählung nicht wesentlich mehr dar, als eine Gruppe von symbolischen Kostanten,
    die man auch mit #define hätte einführen können.
    Der Vorteil bei der Verwendung der Aufzählungstypen in C besteht darin, daß zusammengehörige Konstanten
    besser als Gruppe deutlich gemacht werden können.
    Das der Compiler bei der Zuweisung von Werten an Variablen eines Aufzählungstyps eine Typüberprüfung
    vornimmt gilt nur für C++ - und nicht für C-Compiler.



  • egon2 schrieb:

    In C stellt eine enum-Aufzählung nicht wesentlich mehr dar, als eine Gruppe von symbolischen Kostanten,
    die man auch mit #define hätte einführen können.

    Nein, mit define kann man keine symbolischen Konstanten einführen, sondern nur Ersetzungsanweisungen für den Preprozessor geben.

    enum { BUFFER_SIZE = 2 };
    
    void foo() {
      enum { BUFFER_SIZE = 8 };
      // ...
    }
    
    void bar() {
      enum { BUFFER_SIZE = 1024 };
      // ...
    }
    


  • egon2 schrieb:

    Das der Compiler bei der Zuweisung von Werten an Variablen eines Aufzählungstyps eine Typüberprüfung
    vornimmt gilt nur für C++ - und nicht für C-Compiler.

    halte ich für'n gerücht. ich kenne mindestens 3 oder 4 C-compiler, die das machen.

    rüdiger schrieb:

    mit define kann man keine symbolischen Konstanten einführen, sondern nur Ersetzungsanweisungen für den Preprozessor geben.

    was faktisch dasselbe ist.
    🙂



  • +fricky schrieb:

    rüdiger schrieb:

    mit define kann man keine symbolischen Konstanten einführen, sondern nur Ersetzungsanweisungen für den Preprozessor geben.

    was faktisch dasselbe ist.
    🙂

    Nein, überhaupt nicht. Siehe mein Beispiel.



  • Auch cool ist folgendes

    typedef enum { EINS, ZWEI, DREI } Zahl;
    
    int func()
    {
       Zahl zahl;
    
       /* ... */
    
       switch(zahl) {
          case EINS:
             /* ... */
          break;
          case ZWEI:
             /* ... */
          break;
       }
    }
    

    Gibt ne Warnung weil ich DREI vergessen hab.



  • rüdiger schrieb:

    +fricky schrieb:

    rüdiger schrieb:

    mit define kann man keine symbolischen Konstanten einführen, sondern nur Ersetzungsanweisungen für den Preprozessor geben.

    was faktisch dasselbe ist.
    🙂

    Nein, überhaupt nicht. Siehe mein Beispiel.

    ich meinte nur das 'konstanten einführen' geht mit #define genauso gut.
    zu deinem beispiel: ob's wirklich 'ne tolle idee ist, vorhandene enum-konstanten temporär innerhalb von funktion zu 'überschreiben', ist ne andere frage. ich würde sowas nicht machen.
    🙂



  • +fricky schrieb:

    ob's wirklich 'ne tolle idee ist, vorhandene enum-konstanten temporär innerhalb von funktion zu 'überschreiben', ist ne andere frage. ich würde sowas nicht machen.
    🙂

    Noch nie Code geschrieben 😮

    Es interessiert mich lokal doch garnicht ob es zufällig eine konstante gibt die gleich heisst. für sowas haben wir ja scopes.

    super beispiel ist hier zB max()

    #define muss man meiden wo geht. und bei konstanten gehts ganz gut.

    merkt man aber erst bei groesseren projekten wenn es zu bösen kollisionen kommt. die winapi zeigt zB wie man es auf keinen fall machen darf... was da für fehler entstehen durch das ewige rum #definee...



  • Shade Of Mine schrieb:

    Noch nie Code geschrieben

    nee, eher zu viel schlechten code gesehen. ich hab' mir angewöhnt, globale symbole nie umzudefinieren, auch nicht, wenn's nur innerhalb einer funktion gültig ist. aber kann jeder machen wie er will, nur sollte er hoffen dass ich seinen code nicht reviewen oder debuggen muss, weil ich bei sowas immer fürchterlich aggressiv werde.

    Shade Of Mine schrieb:

    #define muss man meiden wo geht. und bei konstanten gehts ganz gut.

    wie war nochmal das wort für 'unkritisches festhalten an lehrmeinungen und glaubenssätzen'? enums sind besser für konstanten, aber #defines sind schon nicht das schlechteste:

    enum {MY_CONST=3};  // gut
    #define MY_CONST 3  // geht so
    const int my_const = 3;  // ganz grosser mist
    

    🙂


Anmelden zum Antworten