präprozessr anweisung vs typedef vs const



  • nwp2 schrieb:

    Hmm, also ich habe unions und enums schon gebraucht.
    Und ich halte wenig davon Variablen per defines zu definieren, ich halte const-Variablen da für sinnvoller, weil es so typabhängig ist, aber das kann natürlich auch ein Nachteil sein. Aber wahrscheinlich ist es egal.

    Es geht ja auch nicht um Variable, sondern um echte, echt konstante Werte. Die sind in den Standardlibs nunmal als defines abgelegt.
    const- Vars machen eigentlich nur Sinn, wenn Du dem Compiler sagen kannst, daß er sie im ROM ablegen soll (sonst kopiert der Startupcode sie ins RAM um) und Du die paar gesparten Bytes wirklich brauchst. Das dödelige extern ist der Preis dafür, den man dann zu zahlen hat.

    Aber darf ja jeder programmieren, wie er will ... 😃



  • nwp2 schrieb:

    Und ich halte wenig davon Variablen per defines zu definieren

    das geht ja auch nicht. aber konstanten kannste mit #define anlegen, die sind dann wirklich so richtig konstant.

    nwp2 schrieb:

    ...ich halte const-Variablen da für sinnvoller

    ich z.b. verwende 'const' total selten, fast nie.
    🙂



  • µngbd schrieb:

    Nö, dafür gibt's M_PI_2

    ich denke ich sollte mal die math.h genauer unter die lupe nehmen 🙂



  • Bashar schrieb:

    [quote="µngbd"Warum eigentlich nicht?

    Weil enums durch ganze Zahlen repräsentiert werden. Syntaktisch mag das so gehen, aber da wird dann 3.14159 in 3 konvertiert.[/quote]
    Gibt's dafür einen profanen Grund, oder ist das einfach so, weil es einfach so ist?

    nwp2 schrieb:

    Und ich halte wenig davon Variablen per defines zu definieren, ich halte const-Variablen da für sinnvoller, weil es so typabhängig ist, aber das kann natürlich auch ein Nachteil sein.

    Deswegen gibt es ja die Suffizes für Zahlen-Literale. Im schlimmsten Fall könnte man auch einen cast mit in das Makro nehmen.

    Ich finde enum's ganz nett, wenn man sich damit ein paar "Symbole" anlegen kann, ohne die Werte selbst explizit zu machen. Wenn ich aber ein langes 'enum' voll mit expliziten Zahlen sehe, verstehe ich den Vorteil nicht mehr so recht.
    🙂



  • Diese ganzen #defines aus math.h, M_PI usw., sind leider nicht im Standard.



  • µngbd schrieb:

    Bashar schrieb:

    µngbd schrieb:

    Warum eigentlich nicht?

    Weil enums durch ganze Zahlen repräsentiert werden. Syntaktisch mag das so gehen, aber da wird dann 3.14159 in 3 konvertiert.

    Gibt's dafür einen profanen Grund, oder ist das einfach so, weil es einfach so ist?

    enums sind Aufzählungstypen, eigentlich macht man damit sowas wie MONTAG, DIENSTAG, MITTWOCH usw. Damit beliebige Konstanten zu definieren war nie der Sinn, das macht man nur, weil #define wohl neuerdings pöhse ist und weil consts external linkage haben.



  • Bashar schrieb:

    Diese ganzen #defines aus math.h, M_PI usw., sind leider nicht im Standard.

    Oje, das stimmt. Ich hab mich schon wieder mal auf die manpages verlassen. Man muss sich das abgewöhnen.
    🙂



  • Bashar schrieb:

    weil #define wohl neuerdings pöhse ist und weil consts external linkage haben

    also da enzieht sich mir der sinn ne konstante die schön in ein register passt sonstwo her zu holen ab in ein #define damit 🙂



  • noobLolo schrieb:

    Bashar schrieb:

    weil #define wohl neuerdings pöhse ist und weil consts external linkage haben

    also da enzieht sich mir der sinn ne konstante die schön in ein register passt sonstwo her zu holen ab in ein #define damit

    dass 'const' #define vorzuziehen ist, wird in C++-kreisen gepredigt. naja, alles was aus der ecke kommt, ist sowieso mit vorsicht zu geniessen.
    🙂



  • ;fricky schrieb:

    dass 'const' #define vorzuziehen ist, wird in C++-kreisen gepredigt. naja, alles was aus der ecke kommt, ist sowieso mit vorsicht zu geniessen.

    ja bei kleinen dingen fängts an:)
    nicht das hier ein c vs. c++ off-topic thread entsteht 🤡



  • µngbd schrieb:

    Bashar schrieb:

    Diese ganzen #defines aus math.h, M_PI usw., sind leider nicht im Standard.

    Oje, das stimmt. Ich hab mich schon wieder mal auf die manpages verlassen. Man muss sich das abgewöhnen.
    🙂

    Wieso? Wenn's im Header nicht drinsteht, merkste das, wenn der Präppi oder Compiler meckert. Dann schreibst Du's einfach in math.h mit rein, fertig.



  • Bashar schrieb:

    supertux schrieb:

    Ich hab ehrlich gesagt noch nie ausprobiert und hab gar nicht dran gedacht, als ich den Beitrag schrieb. 🙄

    Wieso schreibst du dann, dass du das selbst so machst? Du simulierst dadurch eine fundierte Aussage.

    oje oje, jetzt habe ich ein bisschen Verwirrung gestiftet. Ich verwende sehr wohl enums anstatt #define, aber meine Werte sind stets hexazahlen, also sowas in der Art

    enum was_auch_immer {
      CAN_SDO_ERR_REG    = 0x1001,
      CAN_SDO_COBID_SYNC = 0x1005,
      CAN_SDO_SAVE_PARM  = 0x1010,
      ...
    }
    

    aber ich hab noch nie sowas mit floats gemacht, deshalb habe ich gar nicht dran gedacht, als ich den Beitrag schrieb. So habe ich das gemeint.



  • das leben könnt so einfach sein 😉

    #define CAN_SDO_ERR_REG 0x1001
    #define CAN_SDO_COBID_SYNC 0x1005
    #define CAN_SDO_SAVE_PARM 0x1010
    


  • Das was_auch_immer kann man auch weglassen wenns einen nicht interessiert. Aber für sowas ist enum echt nicht geeignet, enum ist nur richtig sinnvoll wenn einen die Werte nicht interessieren.
    Ich würde es aber trotzdem so machen:

    const int CAN_SDO_ERR_REG 0x1001;
    const int CAN_SDO_COBID_SYNC 0x1005;
    const int CAN_SDO_SAVE_PARM 0x1010;
    

    Mich irritiert das wenn der Compiler Code bemeckert und ich in meinen Code kucke und da steht was ganz anderes.

    Der Vorteil mit const int ist, dass sowas hier einen Fehler ergibt:

    struct bla *b;
    ...
    b = CAN_SDO_SAVE_PARM; //eigentlich war b.zustand = CAN_SDO_SAVE_PARM; gemeint
    

    Bei #define sucht man eine Weile.



  • ich finde enums angenhemer, weil ich sie sehr oft in switch Anweisungen verarbeite. Wenn ich was vergesse, teilt mir der Compiler das mit. Das passiert aber nicht mit defines.

    Außerdem lasse ich manchmal den Code nur durch den präpi durchlaufen und da ist es toll, wenn ich immer noch CAN_SDO_COBID_SYNC lese anstatt 0x1005, denn CAN_SDO_COBID_SYNC sagt mir mehr als 0x1005.

    Außerdem kann ich bei Funktionen an den Paramtern festhalten, welche Werte überhaupt möglich sind

    int object_do_something(enum was_auch_immer wai, ....);
    

    klar kann der Benutzer meiner Bibliotheken andere Werte reinschreiben, aber ohne groß dokumentieren zu müssen, wird jeder merken, dass nur die Werte des enums erlaubt sind. Mit

    int object_do_something(int wai, ....);
    

    ginge es nicht.



  • nwp2 schrieb:

    Bei #define sucht man eine Weile.

    dann stell dir für macros eine andere farbe ein z.b. rot oder so??

    const int CAN_SDO_ERR_REG 0x1001;
    const int CAN_SDO_COBID_SYNC 0x1005;
    const int CAN_SDO_SAVE_PARM 0x1010;
    

    wenn das so cool wär würden die konstanten in math.h z.b. M_PI doch

    const int M_PI xyz;// definiert sein sind sie aber nicht sondern
    #define M_PI xyz
    

    supertux schrieb:

    int object_do_something(enum was_auch_immer wai, ....);
    

    ja also damit hast du mich für enums begeistert 🙂



  • noobLolo schrieb:

    supertux schrieb:

    int object_do_something(enum was_auch_immer wai, ....);
    

    ja also damit hast du mich für enums begeistert

    beim debuggen sind sie auch gut, z.b. zeigt der debugger dir den symbolischen namen an. bei #defines siehst du nur den nackten zahlenwert.
    🙂



  • supertux schrieb:

    ich finde enums angenhemer, weil ich sie sehr oft in switch Anweisungen verarbeite. Wenn ich was vergesse, teilt mir der Compiler das mit. Das passiert aber nicht mit defines.

    Wie meinst Du das genau? Welches Vergessen befördert der Compiler zutage?

    SFRs deswegen als enums? Brauch' ich bei meinen Debuggern auch nicht, auf Source Level sehe ich den Quelltext (also die C-LOC), da ist noch nichts ersetzt und in ASM kann ich auch mal echt suchen, wenn ich soweit runter muß.

    Ich seh' jetzt einfach nur keinen tieferen Sinn, wenn' man's mir nochmal langsam erklärt, bitte?



  • pointercrash() schrieb:

    supertux schrieb:

    ich finde enums angenhemer, weil ich sie sehr oft in switch Anweisungen verarbeite. Wenn ich was vergesse, teilt mir der Compiler das mit. Das passiert aber nicht mit defines.

    Wie meinst Du das genau? Welches Vergessen befördert der Compiler zutage?

    bsp:

    enum wasauchimmer {
      A,
      B,
      C,
      ...
      X,
      Y,
      Z
    };
    
    void foo(enum wasauchimmer bar)
    {
      switch(bar)
      {
         case A:
         case B:
            mach was;
         ...
      }
    }
    

    angenommen ich habe den Fall für 'K' vergessen (absichtlich :default weggelassen), dann sagt mir der Compiler, dass der Fall 'K' nicht behandelt wird. Beim Compilieren merke ich den Fehler. Das mache ich solange bis der Compiler mir entweder keine Warnung mehr spuckt oder mir nur von den jenigen warnt, die unter 'default:' fallen würden. Erst dann schreib ich 'default:'.

    Außerdem werden bei enums mir die Konstanten semantisch zusammengefasst, das die Verwendung der Bibliothek erleichtert. Auch Doxygen zeigt automatisch die zusammengefasste Doku an einer Stelle. Wenn ich nur #defines hätte, wäre das nicht möglich.



  • pointercrash() schrieb:

    Brauch' ich bei meinen Debuggern auch nicht, auf Source Level sehe ich den Quelltext (also die C-LOC), da ist noch nichts ersetzt...

    nimm mal das:

    // in einer h datei
    typedef enum time_machine
    {
      gestern,
      heute,
      morgen,
    } time_machine_t;
    
    ------------- snip -------------
    
    // hier willst du debuggen
    void f (time_machine_t b)
    {  // <-- breakpoint
       ...
    }
    
    ------------- snip -------------
    
    // andere c-datei von 1000 dateien
    ...
    f (morgen);
    ...
    

    ^^ wenn du das debuggst, zeigt dir der debugger das 'b' als 'morgen' an. wären es defines, würdest du bloss eine 2 sehen.
    🙂


Anmelden zum Antworten