Problem bei Fehlermeldung: invalid operands to binary |

Gast #6048838
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?
Gast #6048841
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;
Gast #6048853
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.
Gast #6048868
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. :-)
Gast #6048901
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.
Gast #6048916
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?
Gast #6048927
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren