Forum: Compiler & IDEs Cast zwischen uint8_t* und char* ?


von Typecast (Gast)


Lesenswert?

Hi,

ich renne gerade in ein kleines Problem. Ich habe mir vor längerer Zeit 
angewöhnt so weit es geht un sinn macht auf die inttypes.h 
zurückzugreifen.

Jetzt renne ich blöderweise in ein kleines Problem.

Ich behandeln Strings als uint8_t array. Klingt für mich logisch, denn 
negative Ascii zeichen sind mir bisher noch nicht untergekommen.

Jetzt muss ich allerdings ein paar Funktionen aus der string.h verwenden 
und bekommen daher compilerwarnings:

"expected 'const char *' but argument is of type 'uint8_t *'"
"pointer targets in passing argument 1 of 'atoi' differ in signedness"

Kann ich jetzt einfach uint8_t ohne Bedenken auf const char* casten ?

Ein weiteres Problem. Ich habe einen String der sowohl in der ISR als 
auch im Hauptprogramm verwendet wird. Daher ist er mit volatile uint8_t 
deklariert. Außerhalb der ISR möchte ich den String jetzt gerne auf 
einem LCD ausgeben. Dann bekomme ich die Warnung:

"passing argument 1 discards 'volatile' qualifier from pointer target 
type"

Muss ich den String jetzt vorher in eine nicht volatile variable 
umschaufeln um den String ausgeben zu können ?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Typecast schrieb:
> Ich behandeln Strings als uint8_t array. Klingt für mich logisch, denn
> negative Ascii zeichen sind mir bisher noch nicht untergekommen.

Strings sind char-Arrays.

char.

Nicht "unsigned char" oder "signed char", einfach nur char.

von Typecast (Gast)


Lesenswert?

Okay und wie schaut es mit dem "passing argument 1 discards 'volatile' 
qualifier from pointer target type" aus ?

Um das vorgehen bei der volatile Problematik nochmal an einem Beispiel 
zu veranschaulichen.
1
  volatile char buff[20];
2
  volatile uint8_t buffer_full;
3
4
  ISR() {
5
    if (!buffer_full) {
6
      // Fülle Buff und signalisiere über Flag das buff gefüllt
7
      buffer_full = 1;
8
    }
9
  }
10
11
  uint8_t getBuffVal(char* buff) {
12
     return atoi(buff);
13
  }
14
15
  int main() {
16
    while(1) {
17
      if(buffer_full) {
18
        getBuffVal(buff);
19
        buff_full = 0;
20
      }
21
    }
22
  }

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sieh Dir an, was für ein Argument Du "getBuffVal" übergibst - und was es 
erwartet.

Wenn Du statt

 uint8_t getBuffVal(char* buff)

 uint8_t getBuffVal(volatile char* buff)

schreibst, sollte die Warnung verschwinden.

Allerdings:

Zwar ist es richtig, daß Variablen, auf die sowohl innerhalb als auch 
außerhalb einer ISR zugegriffen wird, als volatile deklariert werden 
sollen, aber andererseits ist das ab einer bestimmten Variablengröße 
auch irrelevant -- wie wahrscheinlich ist es, daß der Compiler den Code 
so optimiert, daß das Array komplett in CPU-Registern gehalten wird?

von Rolf Magnus (Gast)


Lesenswert?

Typecast schrieb:
> ich renne gerade in ein kleines Problem. Ich habe mir vor längerer Zeit
> angewöhnt so weit es geht un sinn macht auf die inttypes.h
> zurückzugreifen.
>
> Jetzt renne ich blöderweise in ein kleines Problem.
>
> Ich behandeln Strings als uint8_t array. Klingt für mich logisch, denn
> negative Ascii zeichen sind mir bisher noch nicht untergekommen.

Für Text gibt es gar kein Konzept von signedness, da man damit nicht 
rechnet. Daher kann es dir ach völlig egal sein, welcher 
darunterliegende Integer-Typ zum Speichern verwendet wird. Der für Text 
vorgesehene ist char, also verwende den auch! Ich verstehe bis heute 
nicht, warum so viele Probleme mit irgendwelchen Vorzeichen bei Text 
haben und nur deshalb dann ihr Texthandling mit irgendeinem anderen 
Datentyp machen. Bei anderen Programmiersprachen macht sowas doch auch 
keiner.

> Jetzt muss ich allerdings ein paar Funktionen aus der string.h verwenden
> und bekommen daher compilerwarnings:
>
> "expected 'const char *' but argument is of type 'uint8_t *'"
> "pointer targets in passing argument 1 of 'atoi' differ in signedness"
>
> Kann ich jetzt einfach uint8_t ohne Bedenken auf const char* casten ?

Sinnvoller wäre es, überall char statt uint8_t zu verwenden. Einen Cast 
braucht man dann eigentlich nur an einer einzigen Stelle, nämlich da, wo 
der Wert ins Hardware-Register geschrieben wird.

von Peter D. (peda)


Lesenswert?

Rolf Magnus schrieb:
> Für Text gibt es gar kein Konzept von signedness, da man damit nicht
> rechnet.

Gibt es doch.
Man kann Texte vergleichen, sortieren oder in Zahlen umwandeln. In 
diesem Fall wandeln diese Routinen intern für sich das char in unsigned 
um.

Eine beliebte Fallgrube ist, ASCII-Umlaute in LCD-Umlaute zu 
konvertieren. Wenn man da nicht umwandelt, gehts in die Hose.

Die (signed) char Festlegung ist Mist, daran besteht kein Zweifel.
Aber die Ur-C-ler haben das nun mal so festgelegt und keiner traut sich, 
daran zu rütteln.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Eine beliebte Fallgrube ist, ASCII-Umlaute in LCD-Umlaute zu
> konvertieren. Wenn man da nicht umwandelt, gehts in die Hose.

Was magst Du meinen? Es gibt keine "ASCII-Umlaute".

von Rolf Magnus (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Rolf Magnus schrieb:
>> Für Text gibt es gar kein Konzept von signedness, da man damit nicht
>> rechnet.
>
> Gibt es doch.
> Man kann Texte vergleichen, sortieren oder in Zahlen umwandeln. In
> diesem Fall wandeln diese Routinen intern für sich das char in unsigned
> um.

Das ist aber erstens, wie du schon sagst, intern, und zweitens hängt das 
auch von der gewünschten Sortierreihenfolge ab. "ASCIIbetisch", wie man 
es manchmal nennt, ist heute oft nicht mehr üblich, da es z.B. 
Großbuchstaben vor Kleinbuchstaben sortiert und Sonderzeichen da dann 
irgendwie drum herum verteilt. Runde Klammern kommen z.B. vor den 
Großbuchstaben, eckige zwischen Groß- und Kleinbuchstaben und 
geschweifte nach den Kleinbuchstaben. Umlaute sind nicht richtig 
einsortiert u.s.w. und bei UTF-8 wird dann sowieso alles noch viel 
komplizierter.

> Eine beliebte Fallgrube ist, ASCII-Umlaute in LCD-Umlaute zu
> konvertieren. Wenn man da nicht umwandelt, gehts in die Hose.

"ASCII-Umlaute" gibt es nicht, und negative Werte gibt's da auch nicht, 
weil ASCII nur 7 Bit nutzt. Und wenn man z.B. ISO-8859-1 verwendet, muß 
man ja eh konvertieren, egal ob der Zeichentyp nun signed oder unsigned 
ist.

> Die (signed) char Festlegung ist Mist, daran besteht kein Zweifel.

Es ist eben nicht als signed festgelegt, und genau das ist Mist. Bei 
short, int, long und long long ist der Default signed, wenn man nichts 
davor schreibt, nur char ist eine Ausnahme, weil ISO C dort sagt, daß 
der Compiler es sich aussuchen kann. Ich hätte es lieber konsistent, so 
daß es bei allen Integer-Typen gleich ist und nicht bei einem vielleicht 
anders, vielleicht aber auch nicht.

von Peter D. (peda)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Was magst Du meinen? Es gibt keine "ASCII-Umlaute".

CP850

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

CP850 ist ebensowenig ASCII wie CP437 und ISO8859-1 ASCII sind.

Alle drei enthalten ASCII auf den ersten 128 Plätzen, aber das ist was 
anderes.

von Peter D. (peda)


Lesenswert?

Rufus Τ. Firefly schrieb:
> CP850 ist ebensowenig ASCII wie CP437 und ISO8859-1 ASCII sind.

Ja, man kann Haare spalten ohne Ende.
Aber wozu?

Peter Dannegger schrieb:
> Eine beliebte Fallgrube ist, ASCII-Umlaute in LCD-Umlaute zu
> konvertieren. Wenn man da nicht umwandelt, gehts in die Hose.

Ich glaube nicht, daß jemand diesen Satz nicht verstanden hat.

von W.S. (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Bei
> short, int, long und long long ist der Default signed,

Tja, einer der vielen Geburtsfehler von C eben. Man hätte (ja, 
konjunktiv mal wieder) char's strikt von allen Integertypen trennen und 
meinetwegen als 8 Bit Größe das Byte einführen sollen. Das hätte 
sämtliche Verwirrungen beseitigt.

Nebenbei sind diese unsäglichen uintX_t auch bloß typedefs und keine 
eigentlichen echten Typen, aber auch diese Diskussion hatten wir schon - 
und zwar fruchtlos.

W.S.

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.