Forum: Mikrocontroller und Digitale Elektronik Problem bei Fehlermeldung: invalid operands to binary |


von Felix (Gast)


Lesenswert?

Nabend,
ich habe eine Frage zu einer Fehlermeldung.
1
static uint8_t _dataPin;
2
static uint8_t _dataPort;
3
4
void WS2818(volatile uint8_t* ddr, uint8_t ddrNewSate, volatile uint8_t* port, uint8_t portNewState, uint8_t dataPin)
5
{
6
  *ddr |= ddrNewSate;
7
  *port |= portNewState;
8
9
  _dataPin = dataPin;
10
  _dataPort = port | (1 << dataPin);
11
}

hierbei bekomme ich die Fehlermeldung:
invalid operands to binary | (have 'volatile uint8_t * {aka volatile 
unsigned char *}' and 'int')

ich verstehe zwar die Worte, aber leider den Sinn nicht dahinter. Was 
genau bedeutet das? Und wieso kann ihc das nicht machen?

von Theor (Gast)


Lesenswert?

Das hängt mit der Zeigernatur von port zusammen - besser ausgedrückt 
damit, dass port ein Zeiger ist und kein Integer. Das geht ja auch aus 
der Fehlermeldung hervor.

Die Ausdrücke:
1
  *ddr |= ddrNewSate;
2
  *port |= portNewState;

sind ausgeschrieben:
1
  *ddr = ddr | ddrNewSate;
2
  *port = port | portNewState;

und nicht, wie Du vermutlich annimmst
1
  *ddr = *ddr | ddrNewSate;
2
  *port = *port | portNewState;

von Nop (Gast)


Lesenswert?

Felix schrieb:

>   _dataPort = port | (1 << dataPin);

In dieser Zeile ist port ein Pointer, den Du mit einem Int verordern 
willst, und das Ergebnis davon willst Du in einem uint8_t speichern? Mit 
ziemlicher Sicherheit meinst Du

[c]_dataPort = *port | (1 << dataPin);[c]

Und da das alles sowieso auf uint8_t läuft und vermutlich auf einem 
8-Bit-Prozessor, willst Du die Veroderung sicherlich nicht als Integer 
durchführen, sondern möchtest vielmehr das hier, weil es schneller geht:

[c]_dataPort = *port | (uint8_t)(((uint8_t) 1) << dataPin);[c]



Theor schrieb:

> Die Ausdrücke:
>   *ddr |= ddrNewSate;
>   *port |= portNewState;
>
> sind ausgeschrieben:
>   *ddr = ddr | ddrNewSate;
>   *port = port | portNewState;

So ein Unsinn.

von Nop (Gast)


Lesenswert?

Ah vergessen, die Tags zuzumachen.

ALso gemeint ist wohl
1
_dataPort = *port | (1 << dataPin);

Und performance-freundlich
1
_dataPort = *port | (uint8_t)(((uint8_t) 1) << dataPin);

von Theor (Gast)


Lesenswert?

Ups. Meine Antwort war leider völlig daneben.


Es ist völlig korrekt anzunehmen, dass:
1
  *ddr |= ddrNewSate;
2
  *port |= portNewState;

äquivalent zu:
1
  *ddr = *ddr | ddrNewSate;
2
  *port = *port | portNewState;

ist.

Sorry.
Sollte erstmal was essen. :-)

von Jemand (Gast)


Lesenswert?

Nop schrieb:
> Ah vergessen, die Tags zuzumachen.
>
> ALso gemeint ist wohl
> _dataPort = *port | (1 << dataPin);
> Und performance-freundlich
> _dataPort = *port | (uint8_t)(((uint8_t) 1) << dataPin);

Schnell geht auch mit -O1 oder höher, dann muss die Wartbarkeit des 
Codes nicht mit deiner Unkenntnis der C-Promotionsregeln 
verschlimmbessert werden.

von Felix (Gast)


Lesenswert?

Nop schrieb:
> [c]_dataPort = *port | (1 << dataPin);[c]

Ja, das war es.
Aber warum ist

Nop schrieb:
> [c]_dataPort = *port | (uint8_t)(((uint8_t) 1) << dataPin);[c]

schneller?

Du castest die 1 auf uint8_t, machst bitshift nach links und castest das 
Ergebnis wieder nach uint8_ t. Aber warum ist das jetzt schneller als 
nur die eins anf für sich um dataPin nach links zu shiften?

von Nop (Gast)


Lesenswert?

Jemand schrieb:

> Schnell geht auch mit -O1 oder höher, dann muss die Wartbarkeit des
> Codes nicht mit deiner Unkenntnis der C-Promotionsregeln
> verschlimmbessert werden.

Dann erklär doch mal, wie Du den an sich unnötigen Cast auf mindestens 
16 Bit verhinderst, der allein deswegen schon ausgelöst wird, weil 1 ein 
Integer ist.

Verläßt Du Dich tatsächlich auf die Compiler-Optimierung?

von Nop (Gast)


Lesenswert?

Oder.. moment, selbst wenn die 1 als 8 Bit behandelt wird, rennt das ja 
eh in die implizite Promotion nach 8 bit, weswegen der cast nichts 
bringt. D'oh.

von Nop (Gast)


Lesenswert?

Nop schrieb:
... nach 16 bit. Argh.

von Theor (Gast)


Lesenswert?

@ Nop

Vielleicht solltest Du erstmal was essen. :-)

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.