Hallo zusammen,
für einen etwas merkwürdigen Anwendungfall benötige ich ein Logik-Array
mit mindestens 59 Bit. Aufgrund der vereinfachten logischen Operationen
wären benannte 64 Bit breite Bitmasken hier sehr praktisch.
Stellt sich die Frage: Können Enums 64 Bit breit sein? Der C-Standard
sagt zu enum nur "muss mindestens Int abbilden können".
Also flugs ausprobiert:
1
enum{
2
e_test1=0x8000000080000000,
3
};
4
5
uint64_ttest=e_test1;
6
printf("\n Enum: %llx\n",test);
7
switch(test)
8
{
9
case0x8000000080000000:
10
printf("Glück gehabt\n");
11
break;
12
default:
13
printf("Pech gehabt\n");
14
}
Der Kompiler zeigt keine neuen Fehler, Warnungen oder Badboxes und das
LCD zeigt den korrekten Wert an mit dem Hinweis, ich habe Glück gehabt.
Damit kommen Folgefragen:
a) Wieso unterstützt der ARM-GCC 64 Bit breite Enums?
b) Werden dadurch plötzlich alle Enums im Binary 64 Bit breit?
c) Kann ich mir mit den breiten Enums irgendwie in den Fuß schießen?
Walter T. schrieb:> a) Wieso unterstützt der ARM-GCC 64 Bit breite Enums?
Warum sollte er nicht? Sofern er int64_t kennt, d.h. 64-Bit-Werte
überhaupt verarbeiten kann, würde ich das erwarten.
enums sind nur hübsche Konstanten, mehr nicht. Da steckt kein
Spezialcode dahinter.
> b) Werden dadurch plötzlich alle Enums im Binary 64 Bit breit?
Finde es selbst heraus, der sizeof -Operator dürfte Dir da helfen.
Walter T. schrieb:> mit mindestens 59 Bit.
Klingt nach DCF-77. Die Wahnsinnsdatenrate von riesigen 1 Baud kann man
bequem in knallharter Echtzeit zu den Zeitvariablen addieren. Sie
erstmal zu speichern ist unnötig.
Enums nimmt man typisch für Aufzählungen und nicht für Bitmasken. Der
Sinn eines 64Bit-Enums erschließt sich mir daher nicht.
Peter D. schrieb:> Der Sinn eines 64Bit-Enums erschließt sich mir daher nicht.
Tarzan hat wieder zugeschlagen.
(die skurrilsten Technik Threads hier auf uc.net)
Peter D. schrieb:> Klingt nach DCF-77.
Es geht immer noch um mein Grafiksystem aus dem alten Thread:
Beitrag "Architektur Grafiksystem"
Da mir noch keine bessere Archtitektur eingefallen ist, werde ich jetzt
mal den ersten Entwurf implementieren und mich von da aus zum
nächstbesseren Entwurf hangeln.
Peter D. schrieb:> Der Sinn eines 64Bit-Enums erschließt sich mir daher nicht.
Der Sinn besteht lediglich darin, innerhalb eines logischen Arrays
möglichst bequem direkt mehrere Einträge verodern zu können.
Rufus Τ. F. schrieb:> Finde es selbst heraus, der sizeof -Operator dürfte Dir da helfen.
Hm. Auf die naheliegende Idee, den sizeof-Operator auf eine Konstante
loszulassen, bin ich tatsächlich noch nie gekommen.
Also flugs ausprobiert:
Irgendwie bin ich doch etwas überrascht, dass Konstanten überhaupt eine
Breite haben. Dann bin ich noch überraschter, dass eine Konstante ohne
Suffix eine größere Breite als Int hat, und dann bin ich noch
überraschter, dass Kontanten innerhalb des gleichen Enums
unterschiedliche Breiten haben können.
Man kann das Verhalten über gcc Optionen beeinflussen.
> Dann bin ich noch überraschter, dass eine Konstante ohne> Suffix eine größere Breite als Int hat
Bem ARM-GCC ist ein int 32bit (4 Bytes) groß.
> dass Kontanten innerhalb des gleichen Enums> unterschiedliche Breiten haben können.
Das kommt mir auch komisch vor.
Walter T. schrieb:> und dann bin ich noch überraschter, dass Kontanten innerhalb des> gleichen Enums unterschiedliche Breiten haben können.
Wenn Du dem enum einen Typ verpasst (oder eine Variable vom Typ Deines
enums anlegst), und sizeof darauf loslässt, solltest Du das größte
Ergebnis bekommen.
kommt beim ersten printf noch das gewohnte Ergebnis mit
unterschiedlichen Größen heraus.
Rufus Τ. F. schrieb:> (oder eine Variable vom Typ Deines> enums anlegst)
Das ist klar. Zumindest, wenn man sich an den Gedanken gewöhnt, dass
0x8000000080000000 aus irgendeinem Grund das Gleiche ist wie
0x8000000080000000ULL.
Enum ist nur eine spezielle Art von Define. Der einzige Unterschied ist,
daß Enums automatisch durchnummeriert werden. Nutzt man diese
Eigenschaft nicht, dann kann man auch gleich Defines hinschreiben.
Daher ist auch klar, daß Enums immer die Breite haben, die durch
Zahlenwert vorgegeben wird.
Als Typ hat ein Enum aber immer die Breite von int.
Mit -fshort-enums kann man die Breite verkleinern, z.B. auf 8Bit beim
AVR-GCC. Da ich nie mehr als 256 Case benötige, reicht mir das aus.
Für Bitmasken nimmt man besser das _BV() Macro.
Peter D. schrieb:> Enums nimmt man typisch für Aufzählungen und nicht für Bitmasken.
Das mag in C so sein, in vielen anderen Sprachen ist das nicht so. Da
gibt es sogar extra-Qualifizierer für Flag-Enums oder sogar spezielle
Mengen-Datentypen, deren Basis eben solche Flag-Enumerationen sind.
Nur weil C da ein wenig behindert ist, muss nicht die ganze restliche
Welt die Beschränkungen dieses anachronistischen Geraffels als
gottgegeben ansehen...
Ich würds nicht machen. Auch wenn
- der Code nie portiert werden muss
- die Wahrscheinlichkeit dass sich das Verhalten vom GCC ändert wohl
recht klein ist
- niemand anderer den Code je anfassen wird
- usw. usf.
ist es trotz allem bad practice.
c-hater schrieb:> Das mag in C so sein, in vielen anderen Sprachen ist das nicht so.
Die Frage bezog sich aber doch auf C. Daher muß man das nicht in jedem
Satz nochmal extra erwähnen.
Walter T. schrieb:> Ausgabe unter Windows: Enum: 8000000080000000> Glück gehabt> s1=8, s2=4, s3=4
Du lässt ja die Größe von den Konstanten ausgeben. Natürlich kann der
Compiler da die Größe festlegen, die ihm am besten gefällt.
Wenn du eine Variable von deinem enum Typ anlegst und davon sizeof
machst, dann sollte das Ergebnis wie erwartet sein.
Peter D. schrieb:> c-hater schrieb:>> Das mag in C so sein, in vielen anderen Sprachen ist das nicht so.>> Die Frage bezog sich aber doch auf C. Daher muß man das nicht in jedem> Satz nochmal extra erwähnen.
Der c-hater muss das aber, so wie er es auch nicht lassen kann, dumme
Schimpfwörter in jedem C Thread unterzubringen.
M.K. B. schrieb:> Walter T. schrieb:>> Ausgabe unter Windows: Enum: 8000000080000000>> Glück gehabt>> s1=8, s2=4, s3=4>> Du lässt ja die Größe von den Konstanten ausgeben. Natürlich kann der> Compiler da die Größe festlegen, die ihm am besten gefällt.> Wenn du eine Variable von deinem enum Typ anlegst und davon sizeof> machst, dann sollte das Ergebnis wie erwartet sein.https://godbolt.org/z/GP4fQR
Peter D. schrieb:> Enum ist nur eine spezielle Art von Define.
Aber eine fundamental verschiedene spezielle Form von #define, wenn man
mehr betrachtet als die Möglichkeit, in globalem Rahmen lexikalische
Konstanten zu definieren. Enum-Namen haben einen kontrollieren
Gültigkeitsbereich, #defines nicht. Enums werden bei Deklaration
berechnet, #defines bei Verwendung.
Rufus Τ. F. schrieb:>> a) Wieso unterstützt der ARM-GCC 64 Bit breite Enums?>> Warum sollte er nicht? Sofern er int64_t kennt, d.h. 64-Bit-Werte> überhaupt verarbeiten kann, würde ich das erwarten.
So blöd ist die Frage nicht. C11: "The expression that defines the value
of an enumeration constant shall be an integer constant expression that
has a value representable as an int."
Peter D. schrieb:> Als Typ hat ein Enum aber immer die Breite von int.
C11: "The choice of type is implementation-defined, ... An
implementation may delay the choice of which integer type until all
enumeration constants have been seen." (lies: optimierbar)
GCC: "Normally, the type is unsigned int if there are no negative values
in the enumeration, otherwise int. If ‘-fshort-enums’ is specified, then
if there are negative values it is the first of signed char, short and
int that can represent all the values, otherwise it is the first of
unsigned char, unsigned short and unsigned int that can represent all
the values.
On some targets, ‘-fshort-enums’ is the default; this is determined by
the ABI."
gcc -c -O -pedantic enum2.c
enum2.c:1:12: warning: ISO C restricts enumerator values to range of
‘int’ [-pedantic]
Vincent H. schrieb:> ist es trotz allem bad practice.
Ich wäre einer Variante besserer Praxis nicht abgeneigt. Den
Anwendungsfall habe ich im vom mir verlinkten Thread ja recht
ausführlich dargelegt.
Momentan implementiere ich tatsächlich diese "bad practice", um den
Ansatz für Verbesserungen zu finden.