Hallo, ich es möglich, einem enum in C eine definierte Datenlänge zu zuweisen? Ich möchte mit einem enum bestimmte Befehle für ein Flash verknüpfen, d.h. einen Frame senden, dessen einer Teil eben Bytegroße Commandos beinhaltet, welches dann z.B. 0x20 lauten. Es ist also wichtig, dass das enum nicht intern auf 16 oder 32 Byte aufgebläht wird, weil dahinter ja unmittelbar weitere Anweisungen oder Nutzdaten folgen. Das enum darf daher nur genau 1 Byte groß sein. Geht das?
In standard C ist das leider nicht vorgesehen. Falls Du GCC verwendest, kann man es aber mit "-fshort-enums" erzwingen.
#define FLASH_CMD_1 0x20 #define FLASH_CMD_2 0x21 tut's nicht?
In C++11 wäre das möglich:
1 | enum flash_command: uint8_t { ... }; |
In C musst du halt den gewünschten Typ überall verwenden (C nimmt es mit der Typ-Prüfung eh nicht so genau):
1 | enum flash_command { ... }; |
2 | |
3 | struct flash_frame { |
4 | uint8_t command; // actually enum flash_command |
5 | ...
|
6 | };
|
Alternativ ebenfalls nur für GCC: Benutze im Beispiel von Clemens:
1 | struct __attribute__ ((__packed__)) flash_frame { |
2 | enum __attribute__ ((__packed__)) command{ ... }; |
3 | ... |
4 | }; |
das hat denselben Effekt (=> Alignment 1 und enum in Mindestgröße) und sollte direkt verständlich sein.
Gängig ist, die Konstanten als Enum zu definieren und dann einen anderen Typen als Variable zu verwenden:
1 | enum { |
2 | CMD_A = 0x01, |
3 | CMD_B = 0x02, |
4 | };
|
5 | |
6 | typedef unsigned char command_t; |
7 | |
8 | command_t cmd = CMD_A; |
Joe F. schrieb: > #define FLASH_CMD_1 0x20 > #define FLASH_CMD_2 0x21 > > tut's nicht? Enum ist besserer Stil. Es dient in C in erster Linie zur Dokumentation und Erhöhung der Verständlichkeit. Außerdem kann man sich dann noch warnen lassen wenn man ein case label vergisst oder wenn man inkompatible Vergleiche durchführt. Und der Wert wird im Debugger mit Namen angezeigt. Und man gewöhnt sich schonmal daran seine Datentypen weniger stiefmütterlich zu behandeln und ihnen mehr Bedeutung zukommen zu lassen für die Zeit die nach C kommen wird, denn wenn es eins gibt über das sich alle einig sind dann daß das implizite Typeschlampe in C für eine statisch getypte Sprache unter aller Sau ist und man den selben Designfehler nicht wieder zulassen würde könnte man die Zeit nochmal zurückdrehen und K. und R. persönlich auf die Finger klopfen bevor das Kind in den Brunnen fällt.
:
Bearbeitet durch User
enum schrieb: > enum mit genau 1 Byte Datenverbrauch Ein Enum in C verbraucht keine Daten, wenn du damit Speicherplatz meinst. Alles andere ist die Kunst des Künstlers, was er damit macht.
Beitrag #4944824 wurde von einem Moderator gelöscht.
IMHO hat das Probem mit Mikrocontrollern im Speziellen herzlich wenig zu tun, sondern ist eher ein Problem des Compilers.
Die Enums machen nur Sinn, wenn Du entsprechende Compiler-Warnungen beachtest. Falls der Compiler keine 8-Bit kann, nimm Lint und mache Dir Deinen eigenen Typen (notfalls mit cast um das Beispiel von Nase) Falls Du mehrere enums in einer Struktur hast, könntest Du { enum ecommands command1 : 8; enum ecommands command2 : 8; } versuchen.
Achim S. schrieb: > Falls Du mehrere enums in einer Struktur hast, könntest Du > { > enum ecommands command1 : 8; > enum ecommands command2 : 8; > } > versuchen. Macht aber Probleme wenn man mal den Offset oder Pointer zu diesem Member braucht, dann weigert sich der Compiler. Genau das Problem hatte ich letztens, ich bin also wieder davon abgekommen und bestehe stattdessen darauf daß mit -fshort-enums kompiliert wird (ist nicht schwer denn das ist im zugehörigen Makefile festgelegt). Erzwingen kann man das auch mit einem compile-time assert auf ein sizeof()
1 | _Static_assert (sizeof(enum foo) == 1, "this code must be compiled with -fshort-enums"); |
und ein paar Worten Dokumentation gleich daneben so daß wenn irgendwer in 12 Jahren den Code wieder ausgräbt und mit dem "falschen" Compiler oder den falschen Optionen kompilieren will ihm das schon beim Compilieren um die Ohren fliegt und er weiß nach welchem Compilerschalter er suchen muss (jeder anständige Compiler wird eine vergleichbare Option haben, erst recht in der Zukunft in der alles noch viel ausgereifter sein wird als es heute schon ist). Und vielleicht gibts bis dahin auch gar kein C mehr.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.