mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Enum als Char


Autor: Dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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! :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.ä.
enum meine_enum {
  eins,
  zwei,
  drei
};


void machwas(enum meine_enum arg) {
  /* arg braucht einen Integer */
}

void machwas_anderes(uint8_t arg) {
  /* geht genauso und spart Platz */
}

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
enum foo {
   FOO_ZERO,
   FOO_ONE,
} __attribute__((packed));

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Autschn. :-]

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Sven P. (haku) Benutzerseite
Datum:

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

Autor: Henry (Gast)
Datum:

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

typedef enum
{
}
char VAR_TYPE;

Autor: Dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
typedef enum
{
}
char VAR_TYPE;

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
void SetColor( uint8_t color );

erzählt mir nicht sehr viel darüber, welche Werte als Argumente zulässig 
sind und welche nicht.
enum PenColor { Black, White, Red, Green };

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
//
// Datatype and valid values for Pen Colors
//
typedef uint8_t PenColor;
#define BLACK  0
#define WHITE  1
#define RED    2
#define GREEN  3


void SetColor( PenColor color );

Autor: Dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
#define PENCOLOR_RED  0
#define PENCOLOR_BLUE 1
// ...
ein stückweit nachempfinden, aber genau für diesen Zweck wurde ja das 
Enum erfunden; warum also nicht auch nutzen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.