Hallo,
ich speichere in meinem Programm das Datum auf folgende Weise:
1
typedefunion{
2
uint32_tdt_int;
3
struct{
4
uint32_tsec:6;
5
uint32_tmin:6;
6
uint32_thr:5;
7
uint32_tday:5;
8
uint32_tmonth:4;
9
uint32_tyear:6;
10
}dt_struct;
11
}date_time_t;
Wenn ich nun aber bestimmte Zeiten speichern oder vergleichen möchte
(sind zur Compilezeit bekannt), dann muss ich entweder einzeln auf die
Variablen zugreifen, oder ich rechne es vorher in ein uint32_t um.
Ginge das nicht auch über ein Makro?
MfG Christian
@ kein Name notwendig: bist du sicher?
Eine union sind doch mehrere Variablen (mit je einem eigenen Namen),
die sich den selben Speicherplatz teilen. Eine davon ist hier eine
struct, aber deshalb muss sie doch trotzdem einen Namen haben, oder?
Zu deinen Vorschlägen: genau das wollte ich eigentlich verhindern.
Vielleicht hab ich das falsch rübergebracht: Es geht nicht (nur) darum,
mir die Tipparbeit zu sparen, sondern das Verwenden mehrerer
Zuweisungen, wo eigentlich eine einzige reichen würde. Es geht eher um
die Zeit, die dann bei der Ausführung gespart wird.
Hmmm, da fällt mir ein, es werden sowieso 4 Byte beansprucht, auf die
ja nacheinander zugegriffen werden muss, oder? Kommt das dann aufs
gleiche raus? Sprich, dauert ein Zugriff auf z.B. uint16_t gleich lange
wie zwei Zugriffe auf uint8_t? Und trifft das dann auch auf meinen
Datentyp zu, wo die Elemente "schief" in der struct liegen, also
nicht genau 8 Byte beanspruchen?
Hallo Christian,
ob eine struct innerhalb einer union einen Namen habe muss, ist von
Compiler zu Compiler unterschiedlich.
Ich kann mich täuschen, aber soweit ich das im Moment überblicke ist
der Zugriff auf dt_int wesentlich schneller als über die Bitfelder.
Das kommt daher, da jedem Bitfeld ein uint32_t zugeordnet ist.
Somit greifst Du über 6 x 32bit zu, wenn Du alle Elemente einzeln
ansprichst.
Aber wie gesagt, genau weiss ich das auch nicht. Ist denke ich mal
ebenfalls abhängig vom Compiler.
Evtl. wäre es besser die Bitfelder zu vergessen.
Speicherst Du die Variablen in einer normalen struct, kannst Du Sie
auch in einem Rutsch via meset() o.ä. setzen.
Nicht das dies nicht auch mit den Bitfeldern möglich wäre, jedoch ist
die eigentliche Wertzuweisung dann wesentlich komplizierter.
Gleiches gilt für die Datenauswertung.
Ich würde einfach ne struct aus 6 Byte-Variablen nehmen.
Bitfelder werden deshalb sehr selten verwendet, weil sie in der Regel
sehr ineffizient sind.
Um einzelne Bits abzuspalten bzw. wieder zusammen zu setzen, wird ne
Menge Code und CPU-Zeit benötigt, was die 2 zusätzlichen Bytes SRAM
kaum Wert sein dürfte.
Peter
Naja, es geht weniger um die 2 Byte SRAM, sondern darum, dass diese
Zeiten samt ein paar erfassten Daten abgespeichert werden sollen.
Zitat Karsten Brandt:
Ich kann mich täuschen, aber soweit ich das im Moment überblicke ist
der Zugriff auf dt_int wesentlich schneller als über die Bitfelder.
Zitat Peter Dannegger
Um einzelne Bits abzuspalten bzw. wieder zusammen zu setzen, wird ne
Menge Code und CPU-Zeit benötigt, was die 2 zusätzlichen Bytes SRAM
kaum Wert sein dürfte.
Genau deshalb wollte ich es mit einem Makro machen. So dass intern
immer uint32_t verwendet wird, ich aber der Übersichtlichkeit halber
(und in einzelnen Fällen wo ich z.B. nur die Minute brauche) die
Variablen getrennt setzen kann.
@ Jörg: Ja, eigentlich brauch ich es nur auf dem GCC zu compilieren.
Was macht diese Extension genau? Gibts da irgendwo eine Doku dazu?
> Genau deshalb wollte ich es mit einem Makro machen.
Ob du das nun in einem Makro oder ohne machst, ist egal. Das ändert am
Aufwand doch nichts.
> Was macht diese Extension genau? Gibts da irgendwo eine Doku dazu?
Ich würd mal schätzen, im Handbuch von GCC.
> Ich würd mal schätzen, im Handbuch von GCC.
Daraus hatte ich sie hier. Nennt sich "Compound literals",
und ist letztlich genau das, was du willst: die Benennung
einer Konstanten, die im Text angegeben ist (literal) für
ein "compound", also für struct/union/array. Der C-Standard
kennt sowas nur für die Initialisierung, GCC kann sie als
Erweiterung für einen beliebigen konstanten Wert einsetzen.
Den Rest hatte ich dann einfach probiert, ob er das so
compilieren will. Ausprobieren überlasse ich dir :), die
Syntax sollte von meinem Beispiel ja klar sein. Hmm, das
heißt, die C99-Syntax für die Initialisierung bestimmter
Elemente eines "compounds" solltest du zuvor wohl bereits
verstanden haben.
Aus dem, was ich da auf der rechten Seite als Vergleichswert
stehen habe, kannst du natürlich auch allemal einen Makro
schreiben. So viel Zeit hatte ich heute früh nur nicht, ich
hab' das schnell während einer anderen Veranstaltung
zusammengetippert.