Forum: Compiler & IDEs Kann mir jemand diesen Code erklären?


von Andi80 (Gast)


Lesenswert?

Hallo habe einen Code von einem Kollegen bekommen den ich nicht verstehe 
kann mir jemand weiter helfen? Hier ist der Code:
1
#define EventBit(a) (a&0x1F)
2
typedef uint32 StatusType[2];
3
4
static StatusType ActualEvents;
5
6
void Status(EventType EventCode )
7
{
8
 if( EventCode < NUMB_OF_EVT )
9
 {
10
   ActualEvents[ EventCode >> 5] &= ~(1UL<<(EventBit(EventCode)) );
11
 }
12
return;
13
}
EventType ist ein enum das bis 56 geht.

von Peter II (Gast)


Lesenswert?

warum fragst du deinen Kollegen nicht?

Bei welcher Zeile kommt du denn nicht weiter?

von Andi80 (Gast)


Lesenswert?

Weil mein Kollege für 3 Wochen im Urlaub ist und ich mich nun in seine 
Sachen einarbeiten soll.

von Jens M. (dl4aas) Benutzerseite


Lesenswert?

Moin Andi80,

in ActualEvents, das aus zwei 32bit-Zahlen besteht, wird das Bit 
gelöscht, das die Nummer der Eventcodes hat. ActualEvents[1] ist für die 
Bits 55..32 zuständig, [0] für 31..0.

Gruß
Jens

von Andi80 (Gast)


Lesenswert?

Ok das mit dem ersten Teil habe ich verstanden aber den Teil hinter der 
Klammer nicht ganz.Wie würde das ganze aussehen wenn ich es in mehreren 
Schritten mach?

von Jens M. (dl4aas) Benutzerseite


Lesenswert?

Hinter welcher Klammer?

Mal die Kernzeile:

ActualEvents[ EventCode >> 5] &= ~(1UL<<(EventBit(EventCode))

Könnte man als
1
 index = EventCode >> 5;  // die Bits 7..5 des Eventcodes als Index
2
 bitindex = EventBit(EventCode); // die Bits 4..0 als Bitnummer
3
 bitmask = 1UL << bitindex; // bitmaske mit einem Bit gesetzt erstellen
4
                            // je nach Bitnummer
5
 invbitmask = ~bitmask;   // bitmaske invertieren, denn ich will ja loeschen
6
 ActualEvents[index] = ActualEvents[index] & invbitmask;
7
                          // in ActualEvents das eine nicht gesetzte bit 
8
                          // durch ver-und-en loeschen
schreiben.

Wird das so klarer?

von Oliver (Gast)


Lesenswert?


von Andi80 (Gast)


Lesenswert?

Alles klar super jetzt habe ich es verstanden. Besten dank.

von Tom K. (ez81)


Lesenswert?

Hallo Andi,
tu Dir bitte selbst den Gefallen und klammere das a in dem #define noch 
zusätzlich ein. Sonst hängt die Evaluierung des ganzen von der 
Operatorrangfolge in C ab, was spätestens beim unteren Beispiel 
danebengeht, da der "?:"-Operator schwächer bindet als das "&". Genau 
dieser Fehler eines Experten hat mich Stunden meines Lebens gekostet.
1
#include <stdio.h>
2
#include <stdbool.h>
3
#define EventBit(a) (a&0x1F)
4
5
int main(void)
6
{
7
    for (int i=0xF0; i < 0xFF; ++i)
8
    {
9
        int defaultForUnEven = 0x02;
10
        // "ungerade" events durch default ersetzen:
11
        bool isEven = (i % 2 == 0);
12
        int foo = EventBit(isEven ? i : defaultForUnEven);
13
        printf("EventBit (eigentlich mit 0x1F maskiert): 0x%02X\n", foo);
14
    }
15
    return 0;
16
}

Grüße,
Tom

von Karl H. (kbuchegg)


Lesenswert?

Tom K. schrieb:

> tu Dir bitte selbst den Gefallen und klammere das a in dem #define noch
> zusätzlich ein.

> #define EventBit(a) (a&0x1F)


Du bist aber dann hoffentlich gleich noch einen Schritt weiter 
gegegangen und hast noch eine zusätzliche Klammerebene eingezogen?
1
#define EventBit(a) ((a)&0x1F)

von Tom K. (ez81)


Lesenswert?

Hallo Karl Heinz,

ich schon, aber der Kollege von Andi anscheinend nicht. Das Beispiel 
sollte demonstrieren, was passieren kann, wenn man die Klammern 
weglässt. Das habe ich nicht deutlich genug beschrieben.

Wie man an der Ausgabe sieht, ist das einzige, was mit 0x1F maskiert 
wird, die defaultForUneven-Variable:
1
EventBit (eigentlich mit 0x1F maskiert): 0xF0
2
EventBit (eigentlich mit 0x1F maskiert): 0x02
3
EventBit (eigentlich mit 0x1F maskiert): 0xF2
4
EventBit (eigentlich mit 0x1F maskiert): 0x02
5
[...]

Grüße

von Karl H. (kbuchegg)


Lesenswert?

Tom K. schrieb:
> Hallo Karl Heinz,
>
> ich schon, aber der Kollege von Andi anscheinend nicht. Das Beispiel
> sollte demonstrieren, was passieren kann, wenn man die Klammern
> weglässt.

Ah, ok. Passt.

Ich war schon etwas in Eile und hab mir das Beispiel nicht näher 
angesehen.

Mein Standardbeispiel für diesen Fehlertypus sieht so aus

#define TIMES2(x)    2*x


   j = TIMES2( 3 + 2 )


aus dem Code würde man beim schnellen Lesen ein Ergebnis von 10 
erwarten. Tatsächlich ist das Ergebnis aber 8

Warum? Weil die Makroersetzung zu

   j = 2*3 + 2

führt, und das was anderes ergibt als

   j = 2*(3 + 2)

so wie es ursprünglich gedacht war.

#define TIMES2(x)    (2*(x))


In Makros kann man fast nie genug Klammern haben. Und selbst dann ...

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.