Case label does not reduce to an integer constant
-
Ja, beim mir kommt eine Warnmeldung:
warning 'XY' initialized and declared `extern'
Ich benutze ein QCC (www.qnx.org) Compiler.
-
C-Profi-Progger schrieb:
Du musst dafür #define benutzen
muss man glücklicherweise nicht. Man kann auch einfach enum benutzen
enum { XY=88, ZZ=66 };
voilà
-
Ich finde es mit #define am einfachsten machbar:
#define XY 99 #define ZZ 88 //... // nCommand ist vom Typ int!!! // switch (nCommand) { case XY: { //... } break; case ZZ: { //... } break; default: { } } //...
-
WC-Stein schrieb:
Ich finde es mit #define am einfachsten machbar:
Ja, das mag sein. Der Compiler aber legt mehrere defines Kopien im kompilierten Code ab. Es gibt noch ein paar weitere Argumente gegen defines.
-
shuriko schrieb:
Der Compiler aber legt mehrere defines Kopien im kompilierten Code ab.
hä? was genau meinst du damit?
Der einzige Grund, warum ich in solchen Fälle enum statt defines verwende, ist weil switch Anweisungen mir bescheid geben, wenn ich was vergessen hab:
#define PREFIX_VAL1 1 #define PREFIX_VAL2 3 #define PREFIX_VAL3 4 #define PREFIX_VAL4 5 #define PREFIX_VAL5 7 ... void foo(int flag) { switch(flag) { case PREFIX_VAL1: /* CODE */ break; case PREFIX_VAL2: /* CODE */ break; case PREFIX_VAL4: /* CODE */ break; case PREFIX_VAL5: /* CODE */ break; } }
der Compiler teilt mir da nix mit, mach ich aber so:
typedef enum _some_enum { PREFIX_VAL1 = 1, PREFIX_VAL2 = 3, PREFIX_VAL3 = 4, PREFIX_VAL4 = 5, PREFIX_VAL5 = 7 } some_enum; ... void foo(some_enum flag) { switch(flag) { case PREFIX_VAL1: /* CODE */ break; case PREFIX_VAL2: /* CODE */ break; case PREFIX_VAL4: /* CODE */ break; case PREFIX_VAL5: /* CODE */ break; } }
dann würde der Compiler mich warnen, dass ich PREFIX_VAL3 vergessen habe. Das ist, wie gesagt, der einzige Grund, warum ich an dieser Stelle enum vor define vorziehe, ich sehe sonst keinen weiteren Vorteil.
-
supertux schrieb:
shuriko schrieb:
Der Compiler aber legt mehrere defines Kopien im kompilierten Code ab.
hä? was genau meinst du damit?
#defines sind die Präprozessoranweisungen oder reine symbolische Namen. Der Präprozessor ersetzt diese Wörter durch die Werte (z.B. #define XY 66 -> 66), was zu mehreren Kopien dieser Werte führt. Es könnte vorkommen, dass der Compiler diese Namen nicht mitkriegt und in seine Symboltabelle nicht einträgt. Es könnten Unklarheiten im symbolischen Debbugen enstehen. Aber natürlich muss man nicht komplet auf #defines verzichten.
ps: korrigiert mich bitte, falls was nicht stimmt. Danke.
-
WC-Stein schrieb:
Ich finde es mit #define am einfachsten machbar:
Wo soll jetzt der Vorteil sein? Außer dass du natürlich die ganzen Nachteile von #define hast. (Namensraum Verunreinigung, Nicht im Debugger vorhanden etc.)
Bei #define gilt eigentlich immer die Regel: Nur wenn man wirklich muss.
-
shuriko schrieb:
Der Präprozessor erseAtzt diese Wörter durch die Werte (z.B. #define XY 66 -> 66), was zu mehreren Kopien dieser Werte führt.
Und das ist bei echten, vom Compiler ersetzten Konstanten anders?
Es könnte vorkommen, dass der Compiler diese Namen nicht mitkriegt und in seine Symboltabelle nicht einträgt.
Das wird sogar ganz sicher vorkommen, und zwar immer.
-
C-Profi-Progger schrieb:
Ansi-C ist const nicht das was es in ISO-C++ ist.
Sondern?
-
shuriko schrieb:
Sondern?
na, was anderes eben. das sieht man doch schon an den verschiedenen namen, menno!
-
~ficky schrieb:
shuriko schrieb:
Sondern?
na, was anderes eben. das sieht man doch schon an den verschiedenen namen, menno!
Ich meinete CONST.
-
shuriko schrieb:
Ich meinete CONST.
ist mir klar. in C bedeutet 'const' dass es sich um ein nicht veränderbares objekt handelt (der compiler meckert schreibversuche an). in c++ hat 'const' verschiedene bedeutungen.