Forum: Mikrocontroller und Digitale Elektronik Frage zu struct in c


von Daniel S. (supernova01)


Lesenswert?

Hi,

wenn ich das habe:

typedef struct
{
    uint32_t    day     : 5,
                month   : 4,
                year    :13,
                week    : 3,
                calweek : 6,
                leapjear: 1;
}date_t;

das mache:

date_t nav_date, act_date;

dann beide befülle mit Daten...

kann ich für einen Vergleich einfach das machen:

if (nav_date == act_date) ---

oder das, wenn ich alles aus act_date mav_date zuweisen möchte

nav_date=act_date;

Ist es so einfach?

Danke
DS

von Klaus (feelfree)


Lesenswert?

ja.

von (prx) A. K. (prx)


Lesenswert?

Dennis S. schrieb:
> if (nav_date == act_date) ---

Wenn eine Struct Löcher enthält, ist deren Inhalt undefiniert. Der 
blockweise Vergleich ist somit ebenfalls undefiniert. Folglich lässt C 
einen Vergleich von Structs nicht zu.

Mit memcmp ginge es zwar technisch, und wird hier zumindest bei einem 
32-Bit Prozessor mangels Löchern üblicherweise funktionieren, hat aber 
vom Prinzip her das gleiche Problem.

> nav_date=act_date;

Das hingegen geht.

: Bearbeitet durch User
von Gerald K. (geku)


Lesenswert?

Dennis S. schrieb:
> Ist es so einfach?

Nein, funktioniert nur mit c++ (g++ statt gcc)

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Gerald K. schrieb:
> Dennis S. schrieb:
>> Ist es so einfach?
>
> Nein, funktioniert nur mit c++

Und auch dann nur, wenn operator== definiert wurde.

von Gerald K. (geku)


Lesenswert?

(prx) A. K. schrieb:
> Gerald K. schrieb:
>> Dennis S. schrieb:
>>> Ist es so einfach?
>>
>> Nein, funktioniert nur mit c++
>
> Und auch dann nur, wenn operator== definiert wurde.

Genau so ist es, sowohl für den Vergleich als auch für die Zuordnung!

von (prx) A. K. (prx)


Lesenswert?

Gerald K. schrieb:
> Genau so ist es, sowohl für den Vergleich als auch für die Zuordnung!

Zuweisung geht auch in C++ ohne definiertem Operator.

von Thomas (Gast)


Lesenswert?

(prx) A. K. schrieb:
> Zuweisung geht auch in C++ ohne definiertem Operator.

In C auch (mit gcc getestet).

Dennis S. schrieb:
> Ist es so einfach?

Warum testest du das nicht einfach?
Versuch macht kluch...

von Harry L. (mysth)


Lesenswert?

Thomas schrieb:
> Warum testest du das nicht einfach?
Warum lernst du nicht einfach C?

Thomas schrieb:
> Versuch macht kluch...

Das spart dir solche unsinnigen Versuche.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Thomas schrieb:
> Warum testest du das nicht einfach?
> Versuch macht kluch...

Es liefert Dir maximal einen Fehler. Weder Gewissheit wenn es 
funktioniert, noch einen workaround wenn nicht.

Beispiel hier: bei == meckert der Compiler. Also versucht er memcmp und 
das klappt.

Soll er dann annehmen, dass man structs mit memcmp vergleichen kann?

von (prx) A. K. (prx)


Lesenswert?

A. S. schrieb:
> Es liefert Dir maximal einen Fehler.

Was immerhin ein ziemlich sicheres Indiz ist, dass es in C nicht 
zulässig ist. Umgekehrt ist das nicht so klar: Wenn GCC etwas 
akzeptiert, ist es nicht zwangsläufig im Standard erlaubt.

von DerEinzigeBernd (Gast)


Lesenswert?

Strukturzuweisungen sind in C seit C90 zulässig.

Strukturvergleiche kennt C nicht, und Strukturen lassen sich ersatzweise 
nur dann sinnvoll mit memcmp vergleichen, wenn sie gepackt sind, d.h. 
Strukturelemente ohne Rücksicht auf Alignment angeordnet sind.

Andernfalls vergleicht memcmp auch ungenutzte Füllbytes, die reinstes 
Bitrauschen enthalten können. Und das ist nicht Ziel der Übung.

von Klaus (feelfree)


Lesenswert?

Wenn Du, wie im Beispiel, wirklich jedes Bit definierst und auch 
vergleichen willst, könntest Du dir mit einer union abhelfen:

typedef union
{
    struct {
        uint32_t    day     : 5,
                    month   : 4,
                    year    :13,
                    week    : 3,
                    calweek : 6,
                    leapjear: 1;
    };
    uint32_t date;
} date_t;

Dann klappt der Vergleich mittels

if (nav_date.date == act_data.date)

von (prx) A. K. (prx)


Lesenswert?

Klaus schrieb:
> Wenn Du, wie im Beispiel, wirklich jedes Bit definierst und auch
> vergleichen willst, könntest Du dir mit einer union abhelfen

Da Bitfelder ziemlich schwach definiert sind, ist das aber nicht 
garantiert. Vorsichtshalber sollte man dann auf sizeof(date_t)==4 
prüfen, um keine Überraschungen zu erleben. Einem Compiler eines 
16-Bitters könnte sauer aufstossen, dass year über einer 16-Bit Grenze 
liegt, mit Bitlöchern als Folge. In dem Fall würde eine dem angepasste 
Anordnung der Komponenten zu einem anderen Ergebnis führen.

: Bearbeitet durch User
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.