Forum: Mikrocontroller und Digitale Elektronik Enum als Char


von Dave (Gast)


Lesenswert?

Hi,

ich möchte Aufzählungstypen verwenden. Allerdings habe ich in dieser 
Aufzählung nur wenige Elemente, insbesondere weniger als 256, sodass die 
vom Compiler standardmäßig genommene Integer-Variable für ein Enum 
eigentlich unnötig Platz verschwendet. Wie kann ich ein Enum derart 
verwenden, dass nur ein Char als Speicher belegt wird?

Danke für die Hilfe! :-)

von Karl H. (kbuchegg)


Lesenswert?

Gar nicht.
Welchen Basistyp der Compiler für einen enum nimmt ist maximal, wenn 
überhaupt, mit einem pragma oder einem Compilerswitch einstellbar. In 
der Sprache selbst ist nichts dafür vorgesehen.

Aber: enums in C werden überschätzt. Ihr Nutzen ist mehr als gering. Vor 
allem bringen sie nicht die Datentypsicherheit, die man gerne hätte und 
die man sich erwarten würde.

von Sven P. (Gast)


Lesenswert?

Direkt geht das garnicht, der Typ 'enum' wird dir immer mit einer 
Integer-Art daherkommen.

Es hindert dich allerdings niemand, bei Variablen und Parametern etc. 
statt des 'enum'-Types einfach einen uint8_t zu nehmen. Die Enum-Werte, 
die du vorher vereinbarst, tauchen nämlich als globale Konstanten auf 
und sind nicht an einen 'enum'-Typ gebunden.
Lediglich der Compiler könnte dich warnen, wenn du eine 'enum'-Variable 
in 'switch' verbaust und nicht alle Fälle abdeckst o.ä.
1
enum meine_enum {
2
  eins,
3
  zwei,
4
  drei
5
};
6
7
8
void machwas(enum meine_enum arg) {
9
  /* arg braucht einen Integer */
10
}
11
12
void machwas_anderes(uint8_t arg) {
13
  /* geht genauso und spart Platz */
14
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl heinz Buchegger wrote:

> Ihr Nutzen ist mehr als gering.

Am meisten bringen sie dem Debugger, da der die enum-tags statt
der Zahlen anzeigen kann.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sven P. wrote:
> Direkt geht das garnicht, ...

Jein, ist compilerabhängig.  Manche Compiler belegen standardmäßig
den kleinsten möglichen Integer-Datentyp, IAR zum Beispiel.  GCC
belegt standardmäßig einen `int' dafür, aber man kann ihn anweisen,
den kleinsten möglichen Typ zu benutzen, indem man das enum so
deklariert:
1
enum foo {
2
   FOO_ZERO,
3
   FOO_ONE,
4
} __attribute__((packed));

von Sven P. (Gast)


Lesenswert?

Jörg Wunsch wrote:
> Jein, ist compilerabhängig.  Manche Compiler belegen standardmäßig
> den kleinsten möglichen Integer-Datentyp,
Ist dann aber falsch. Ein Eintrag in einer 'enum' kommt nach Standard 
als 'int' daher, entsprechend ist ein 'enum'-Typ ein 'int'. K&R, Seite 
210.

von Dave (Gast)


Lesenswert?

@ Jörg Wunsch (dl8dtl) (Moderator):
Danke!

> Karl heinz Buchegger wrote:
>> Ihr Nutzen ist mehr als gering.
Wenn der Nutzen mehr als gering ist, dann ist je effektiv vorhanden!

von Sven P. (Gast)


Lesenswert?

Autschn. :-]

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sven P. wrote:

>> Jein, ist compilerabhängig.  Manche Compiler belegen standardmäßig
>> den kleinsten möglichen Integer-Datentyp,

> Ist dann aber falsch.

Nein.  C-Standard, 6.7.2.2, Absatz 4:

  Each enumerated type shall be compatible with char, a signed integer
  type, or an unsigned integer type. The choice of type is
  implementation-defined,108) but shall be capable of representing the
  values of all the members of the enumeration. [...]

"implementation-defined" bedeutet dabei, dass die Implementierung das
auch dokumentiert, und das ist bei IAR der Fall (bei GCC natürlich
auch).

von Sven P. (Gast)


Lesenswert?

Auha, welches C ist das? Und ich dachte, wenigstens auf K&R wär verlass 
-- nehm alles zurück und behaupte das Gegenteil.

von Henry (Gast)


Lesenswert?

Sowas habe ich schon gesehen. Man beachte das „char“ als 
Größenspezifizierung.

typedef enum
{
}
char VAR_TYPE;

von Dave (Gast)


Lesenswert?

1
typedef enum
2
{
3
}
4
char VAR_TYPE;

Diese Variante gefällt mir deutlich besser als die 
__attribute__-Methode!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dave wrote:

> Diese Variante gefällt mir deutlich besser als die
> __attribute__-Methode!

Sie hat nur einen Nachteil: sie beißt sich mit der C-Syntax, denn
sie besitzt zwei Datentypen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sven P. wrote:
> Auha, welches C ist das?

ISO/IEC 9899:1999

Leider haben Brian Kernighan und Dennis Ritchie keine 3. Auflage ihres
Buchs fabriziert, die auf die Änderungen der 1999er Version des
Standards eingeht.  Bei ANSI C89 waren sie ja damals relativ schnell
mit der 2. Auflage gefolgt.

von Karl H. (kbuchegg)


Lesenswert?

Dave wrote:
> @ Jörg Wunsch (dl8dtl) (Moderator):
> Danke!
>
>> Karl heinz Buchegger wrote:
>>> Ihr Nutzen ist mehr als gering.
> Wenn der Nutzen mehr als gering ist, dann ist je effektiv vorhanden!

LOL

Aber es steckt in dem was du sagst auch ein Körnchen Wahrheit. Es gibt 
tatsächlich einen minimalen Nutzen von enum: den dokumentatorischen.
1
void SetColor( uint8_t color );

erzählt mir nicht sehr viel darüber, welche Werte als Argumente zulässig 
sind und welche nicht.
1
enum PenColor { Black, White, Red, Green };
2
3
void SetColor( enum PenColor color );

hingegen, gibt mir mit dem 'Datentyp' PenColor einen Ansatzpunkt in die 
Hand, mit dem man die Projektdateien durchforsten kann, um rauszufinden 
welche Werte für color zulässig sind.

Das wars dann aber auch schon. Fast denselben Effekt könnte man auch so 
erreichen
1
//
2
// Datatype and valid values for Pen Colors
3
//
4
typedef uint8_t PenColor;
5
#define BLACK  0
6
#define WHITE  1
7
#define RED    2
8
#define GREEN  3
9
10
11
void SetColor( PenColor color );

von Dave (Gast)


Lesenswert?

Aber: wenn ich ein Enum verwende, dann warnt mich beispielsweise der 
Compiler, wenn ich nicht alle Werte Abfrage!

Und wenn man noch mehr Defintionen verwendet, dann kann das auch schnell 
unübersichtlich werden, welche jetzt zu PenColor gehören, und welche 
nicht. Klar kann man das über aussagekräftige Namen wie
1
#define PENCOLOR_RED  0
2
#define PENCOLOR_BLUE 1
3
// ...
ein stückweit nachempfinden, aber genau für diesen Zweck wurde ja das 
Enum erfunden; warum also nicht auch nutzen?

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.