Die Variable RunMode kann dann jeden der Werte von rmNone bis rmPostRun
annehmen. Die Variable RunModeSet kann keinen, einen, mehrere oder auch
alle Werte von TRunMode beinhalten.
Beim Vergleichen kann man dann mit
1
if (RunMode in [rmPreRun, rmRun, rmPostRun]) then
2
// Machwas
3
else
4
// Machwasanderes
5
;
prüfen, ob RunMode einen der gefragten Werte beinhaltet.
Kann man soetwas ähnliches auch in C mit enums machen?
Man kann aber --außer mit nichtportablen Spracherweiterungen mancher
Compiler-- bei dieser Syntax keine Wertebereiche angeben (also "zwiebel
bis paprika").
Michael Läßig schrieb:> in einer if Bedingung muß ich dann also mitif (x == Gurke || x ==> Kartoffel) ...> arbeiten.
Nicht zwingend.
Wenn die Anzahl der enum-Konstanten nicht größer als die Anzahl der Bits
im verwendeten Datentyp ist, kann man das auch so lösen:
Sowas geht, find ich aber sehr unschön.
enums sollten meiner Meinung nach (und laut Meinung meiner bisherigen
Arbeitgeber) nur als symbolische Bezeichner herhalten, um den Code
lesbarer zu machen. Um Zuständen zB Namen anstatt Nummern verpassen zu
können.
Sobald die Zahl, die durch ein enum-literal repräsentiert wird eine
Rolle spielt, würd ich auf defines ausweichen.
und wenn deine (und die Meinung deiner bisherigen Arbeitgeber) falsch
ist?
Preisfrage: Was ist der große große große Unterschied zwischen einem
enum und einem define?
Haro schrieb:> Sobald die Zahl, die durch ein enum-literal repräsentiert wird eine> Rolle spielt, würd ich auf defines ausweichen.
Was versprichst du (bzw. dein Arbeitgeber) dir davon?
Meiner Meinung nach, werden enum überschätzt. Das was sie sein sollten,
sind sie nicht. Dazu ist ihre Definition zu schwach. enum sind nichts
anderes als Integer, die einen Namen erhalten haben, der sie in den Rang
eines Pseudodatentyps hievt. Das hat Vorteile in der Dokumentation von
Funktionsschnittstellen. Das hat auch Vorteile, dass Debugger
normalerweise mit den Werten gut klar kommen ohne dass ich als
Programmierer erst mal lang im Code nach dem entsprechenden #define
suchen muss. Aber 'Datentyp-sicherheitstechnisch' sind enums genau die
gleiche Katastrophe wie #define.
Für das, was in Pascal Mengen sind, sind enums keine wirklicher Ersatz,
auch wenn es auf den ersten Blick so aussieht. Die Mengen in Pascal sind
schön, aber so schön dann auch wieder nicht, das man ohne sie nicht
auskommen würde. Was nicht heißen soll, dass ich sie für Mumpitz halte -
nicht falsch verstehen.
Karl Heinz schrieb:> Aber 'Datentyp-sicherheitstechnisch' sind enums genau die> gleiche Katastrophe wie #define.
Ähhhh... nein?
1
typedefenum{A,B,C}abc_t;
2
typedefenum{X,Y,Z}xyz_t;
3
4
abc_tabc=A;
5
xyz_txyz=X;
6
7
if(abc==xyz){
8
printf("Error\n");
9
}
führt mit gcc -W -Wall (was Standardeinstellung sein sollte) zu
test4.c:12:13: warning: comparison between ‘abc_t’ and ‘xyz_t’
[-Wenum-compare]
Wobei ich jetzt nicht ausprobieren mag was noch alles verwarnt wird (und
was nicht ;-)
Michael Reinelt schrieb:> führt mit gcc -W -Wall (was Standardeinstellung sein sollte) zu>> test4.c:12:13: warning: comparison between ‘abc_t’ and ‘xyz_t’> [-Wenum-compare]
Warnungen sind nicht normativ.
Nichts und niemand in der C-Norm hindert dich an
Karl Heinz schrieb:> Warnungen sind nicht normativ.
Ja, aber zumindest geb ich dem Compiler eine Chance, zu erkennen was ich
wollte und was nicht (aber schlussendlich gilt auch hier: Das Programm
macht was du schreibst, nicht was du willst)
> Nichts und niemand in der C-Norm hindert dich an>>
1
>abc_tabc=A;
2
>abc=8;
3
>
Leider richtig. Und nicht mal mit extremen -W's meckert er das an :-(
Karl Heinz schrieb:> Aber 'Datentyp-sicherheitstechnisch' sind enums genau die> gleiche Katastrophe wie #define.
Da geb ich dir recht. Man muss einfach wissen was man tut und dass ein
enum dasselbe wie ein int ist. Ich wünsche mir auch, dass ein enum in C
ein eigenständiger Datentyp ist und nur Werte zulässt, die definiert
wurden. So könnte man viele Programme viel sicherer schreiben.
Ich verwende enums gerne dort, wo mich der der Wert der Variable nicht
interessiert, z.B.:
- Zustände einer Zustandsmaschine
- Kennzahl einer union
- Parameter für eine Funktion, die nur einige definierte Werte zulässt
(Wert wird vor der Verwendung geprüft)
Karl Heinz schrieb:> Was versprichst du (bzw. dein Arbeitgeber) dir davon?
Es ist einfach eine weitere Konvention.
Sowas wie "Makros groß" halt. Als Programmierer seh ich sofort was da
los ist. Auf den ersten Blick. Zumindest bei uns halt.
Mal ganz davon abgesehen dass enums je nach Compilerflags
signed/unsigned oder verschieden breit sein können.
Dadurch könnte irgendeine entartete enum-Aritmethik auf einmal nicht
mehr funktionieren wie gedacht (mal abgesehn dass sowas hoffentlich
niemand macht).
Haro schrieb:> Mal ganz davon abgesehen dass enums je nach Compilerflags> signed/unsigned oder verschieden breit sein können.
Es ist aber ein grober Schnatzer, entsprechende Flags wie -fshort-enums
zu setzen, denn das sind keine Optimierungsflags, sondern sie
verändern das Binärinterface (ABI). Ditto für -f[no]-[un]signed-char
oder -f[un]signed-bitfields, -fpack-struct o.ä.
Wenn man das ABI äbdert braucht man sich nicht zu wundern, wenn nix mehr
geht :-)