Cast zwischen uint8_t* und char* ?

Gast #3542968
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 ?
Gast #3543027
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
  }
Persönliche Seite #3543174
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?
Gast #3543623
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.
#3543662
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.
Gast #3543673
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.
Gast #3564527
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.

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