Forum: Mikrocontroller und Digitale Elektronik enum mit genau 1 Byte Datenverbrauch


von enum (Gast)


Lesenswert?

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?

von Irgendwer (Gast)


Lesenswert?

In standard C ist das leider nicht vorgesehen.
Falls Du GCC verwendest, kann man es aber mit "-fshort-enums" erzwingen.

von Joe F. (easylife)


Lesenswert?

#define FLASH_CMD_1 0x20
#define FLASH_CMD_2 0x21

tut's nicht?

von Clemens L. (c_l)


Lesenswert?

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
};

von Irgendwer (Gast)


Lesenswert?

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.

von Nase (Gast)


Lesenswert?

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;

von Bernd K. (prof7bit)


Lesenswert?

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
von Codejongleur (Gast)


Lesenswert?

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.
von Wolfgang (Gast)


Lesenswert?

IMHO hat das Probem mit Mikrocontrollern im Speziellen herzlich wenig zu 
tun, sondern ist eher ein Problem des Compilers.

von A. S. (Gast)


Lesenswert?

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.

von Bernd K. (prof7bit)


Lesenswert?

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
Noch kein Account? Hier anmelden.