Forum: Mikrocontroller und Digitale Elektronik Anzahl der Elemente in einer Enumeration


von Enumeration (Gast)


Lesenswert?

Hi,

ich möchte die Anzahl der Elemente in einer Enumeration zählen und ggf. 
eine Fehlermeldung ausgeben, sofern es die Bytegrenze überschreitet.

Dafür habe ich mir folgendes gedacht:
1
typedef enum ENUMERATION_e {
2
3
   ENUMERATOR_ONE = 1,
4
   ENUMERATOR_TWO,
5
   ENUMERATOR_THREE,
6
7
   _ENUMERATOR_COUNT
8
9
} FLAGS;
10
11
#if (_ENUMERATOR_COUNT > 7)
12
#error Too much enumerators in ENUMERATION_e
13
#endif

Leider funktioniert das aber nicht. Der Fehlerfall tritt nie ein.

Was mache ich hier falsch bzw. was für Alternativen gibt es?

Vielen Dank!

von g457 (Gast)


Lesenswert?

> Leider funktioniert das aber nicht.

Der Enumerator _ENUMERATOR_COUNT interessiert den Präprozessor nicht.

von Karl H. (kbuchegg)


Lesenswert?

Enumeration schrieb:

> Was mache ich hier falsch

Das ist leicht zu beantworten.
Du trennst nicht zwischen Präprozessor und Compiler.

Jede Zeile, deren erstes Zeichen ein # ist, ist eine Anweisung an den 
Präprozessor. Der Präprozessor weiß aber nichts von C (ok, das ist jetzt 
ein wenig plakativ, aber in deinem Fall ist genau das das Problem).
Der Präprozessor macht im Grunde ledglich Textarbeiten (zb Texte durch 
andere Texte ersetzen) am Programmtext, ehe dann der eigentliche 
Compiler das so aufgearbeitete Programm zu Gesicht bekommt.

D.h. der Präprozessor kann dem Compiler zuarbeiten, aber nicht 
umgekehrt.
Für den Präprozessor ist dein enum im Grunde einfach nur Text ohne 
Bedeutung. Mehr nicht.

> bzw. was für Alternativen gibt es?

Das kannst du nur zur Laufzeit lösen. Dein Programm checkt am Anfang in 
main() die bewusste Konstante und macht irgendwie auf sich aufmerksam.

von g457 (Gast)


Lesenswert?

> Das kannst du nur zur Laufzeit lösen.

Och ∗gehen∗ tut das schon auch statisch, z.B. so:
1
$ cat test.c
2
typedef enum ENUMERATION_e {
3
4
   ENUMERATOR_ONE = 1,
5
   ENUMERATOR_TWO,
6
   ENUMERATOR_THREE = 256,
7
8
   _ENUMERATOR_COUNT
9
10
} FLAGS;
11
12
enum helper_t {
13
  helper = 1 /(!!(_ENUMERATOR_COUNT <= 256))
14
};

Der gcc meckert dann
1
$ gcc -Wall -c -o /dev/null test.c 
2
test.c:13:13: warning: division by zero [-Wdiv-by-zero]
3
test.c:14:1: error: enumerator value for ‘helper’ is not an integer constant
wenn ENUMERATOR_THREE == 256 oder eben auch nicht (so wies oben steht).

Nennt sich im Ende static assert. Noch ein nettes Makro aussen rum.. 
weil schön ist was anderes..

von g457 (Gast)


Lesenswert?

arrgs, streiche '(so wies oben steht)', setze '(wenn man die feste 
Zuweisung für ENUMERATOR_THREE auskommentiert und damit die 
Anforderungen erfüllt)'
</ingrid>

von Karl H. (kbuchegg)


Lesenswert?

g457 schrieb:

> enum helper_t {
>   helper = 1 /(!!(_ENUMERATOR_COUNT <= 256))
> };[/code]

<lach>
Ja. An sowas hatte ich tatsächlich nicht gedacht.

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.