Hallo zusammen,
ich habe keine sinnvollere Überschrift gefunden. Ich habe ein paar
Funktionen implementiert, die Rücksicht auf die Integer-Breite nehmen
müssen:
1 | uint8_t complfkt_uint8(uint8_t val1,int8_t val2);
|
2 | int8_t complfkt_int8(int8_t val1,int8_t val2);
|
3 | uint16_t complfkt_uint16(uint16_t val1,int16_t val2);
|
4 | int16_t complfkt_int16(uint16_t val1,int16_t val2);
|
Jetzt will ich diese Funktionen noch für Datentypen mit
plattformabhängigen Bitbreiten nutzen. Folgendes geht nicht:
1 | #if sizeof(uint_fast8_t) == sizeof(uint8_t)
|
2 | uint_fast8_t complkft_uint_fast8(uint_fast8_t val1, int_fast8_t val2)
|
3 | {
|
4 | return complfkt_uint8(val1,val2);
|
5 | }
|
6 | #elif sizeof(uint_fast8_t) == sizeof(uint16_t)
|
7 | uint_fast8_t complkft_uint_fast8(uint_fast8_t val1, int_fast8_t val2)
|
8 | {
|
9 | return complfkt_uint16(val1,val2);
|
10 | }
|
11 | #elif ...
|
12 | #else
|
13 | #error "unexpected width of type uint_fast8_t"
|
14 | #endif
|
da der sizeof-Operator nicht vom Präprozessor ausgewertet werden kann,
beschreibt aber ganz gut mein Ziel: Ich will Operationen mit Datentypen
mit plattformabhängiger Bitbreite auf fertige Funktionen mit fester
Bitbreite zurückführen, um nicht alles mehrfach implementieren zu müssen
und um ein wenig Programmspeicher zu sparen.
switch/case kann den sizeof-Operator als Label benutzen und der
Optimierer dürfte die toten Zweige und die Abfrage mit dem immergleichen
Ergebnis auf jeder Plattform direkt eliminieren - allerdings steht
offiziell erst zur Laufzeit der Funktion fest, ob überhaupt ein Fall
getroffen wird:
1 | uint_fast8_t complkft_uint_fast8(uint_fast8_t val1, int_fast8_t val2)
|
2 | {
|
3 | switch(sizeof(uint_fast8_t)) {
|
4 | case sizeof(uint16_t) return complfkt_uint16(val1,val2);
|
5 | case sizeof(uint8_t) return complfkt_uint8(val1,val2);
|
6 | ...
|
7 | default: error("function is undefined for type "uint_fast8_t")
|
8 | }
|
9 | }
|
Kann einer der C-Gurus dazu einen Tipp geben?
Viele Grüße
W.T.