Datum: 27.04.2008 19:37
Hallihallo, bin gerade an einem Programm. Hier die relevanten schnipsel:
void function(uint8_t *text) { } int main(void) { function("Hallo"); } |
Der Compiler motzt beim Funktionsaufruf mit folgender Meldung: "warning: pointer targets in passing argument 1 of `function` differ in signedness" Was ist da los? Beim zweiten Durchlauf des Compilers verschwindet die Warnung. Compiliert wird mit WinAVR im AVRstudio Gruss Mario
Datum: 27.04.2008 19:44
Deine Funktion erwartet einen u(nsigned)int_8*, für "Hello" wird aber ein char* erzeugt, der normalerweise signed ist. Also warnt der Compiler. Wenn der Funktionsparameter ein pointer auf einen char sein soll, warum nimmst du dann dafür keinen char*? >Beim zweiten Durchlauf des Compilers verschwindet die >Warnung. Das sollte (und kann) eigentlich nicht sein. Oliver
Datum: 27.04.2008 19:46
Schau dir mal die Wertebereiche von uint8_t (unsigned int 8 bit) und int8_t (signed int 8 bit). Deine Funktion möchte unsigned Daten aber du übergibst signed Daten (Strings sind bei gcc signed).
Datum: 27.04.2008 19:47
Drei Möglichkeiten: Erstens:
/* Parameter als char vereinbaren */ void function(char *text) { } int main(void) { function("Hallo"); } |
Zweitens:
void function(uint8_t *text) { } int main(void) { /* Zeiger casten */ function((uint8_t *) "Hallo"); } |
Drittens: Quelltext beibehalten und dem Compiler ein -munsigned-char mit geben. Dann: >Beim zweiten Durchlauf des Compilers verschwindet die >Warnung. Die Warnung verschwindet net, aber der Quelltext wird beim zweiten Durchlauf nicht mehr compiliert...dafür sorgt das Makefile. Mach mal einen Durchlauf (erwartungsgemäß kommt dein Fehler), dann mach noch einen (kein Fehler mehr), dann setz das Datum der letzten Änderung auf aktuell (einmal Speichern bzw. "touch <datei>.c"), dann kompilier nochmal...dann sollte dein Fehler wieder da sein.
Datum: 27.04.2008 19:53
Huiii, Danke vielmals für die Erläuterungen! Jetzt klappt es. Und doch: die Warnung verschwindet nach dem zweiten mal compilieren und das Proggi tut was es soll. Was meinst du mit deiner dritten Möglichkeit? Bzw. wie machen? Herzlichen Gruss und vielen Dank Mario
Datum: 27.04.2008 20:04
Sven Pauli wrote: > Drittens: > Quelltext beibehalten und dem Compiler ein -munsigned-char mit geben. Falsch. Ein portables Programm muss die Datentypen "char", "signed char" und "unsigned char" als drei voneinander verschiedene, nicht direkt zuweisungkompatible Datentypen behandeln -- egal, ob "char" nun in der konkreten Implementierung vorzeichenbehaftet ist oder nicht. Das bedeutet, dass alle Übergänge zwischen diesen Typen einen Typecast brauchen, damit sichergestellt ist, wie die Vorzeichenhaftig- keit zu übertragen ist. In der Praxis dürfte es am sinnvollsten sein, "char" ausschließlich für darstellbare Zeichen zu benutzen, mit deinen keinerlei Mathematik in irgendeiner Form veranstaltet wird, und "signed char" (alias int8_t) bzw. "unsigned char" (alias uint8_t) für Aufgaben, bei denen es um kleine Ganzzahlen geht. Man hat dann typischerweise genau an einer einzigen Stellen einen Typecast, wenn es um den Typ "char" geht, das ist die Stelle, an der die interne Eigenschaft als druckbares Zeichen auf externe Hardware übergeben wird, also bspw. bei der Zuweisung an das UDR der UART.
Datum: 28.04.2008 15:58
Jörg Wunsch wrote: > Sven Pauli wrote: > >> Drittens: >> Quelltext beibehalten und dem Compiler ein -munsigned-char mit geben. > > Falsch. Jo, falsch. Es muss -funsigned-char (-f!) heißen. > Ein portables Programm muss die Datentypen "char", "signed char" > und "unsigned char" als drei voneinander verschiedene, nicht direkt > zuweisungkompatible Datentypen behandeln -- egal, ob "char" nun in > der konkreten Implementierung vorzeichenbehaftet ist oder nicht. Jein. Die Bibel sagt, Char ist entweder_ gleich signed char _oder gleich unsigned char, das ist maschinenabhängig. Wenns um druckbare Zeichen geht, isses aber grundsätzlich unsigned. (K&R-Programmieren in C, 2. Ausg von 1990, Seite 36). > In der Praxis dürfte es am sinnvollsten sein, "char" ausschließlich > für darstellbare Zeichen zu benutzen, mit deinen keinerlei Mathematik > in irgendeiner Form veranstaltet wird, und "signed char" (alias int8_t) > bzw. "unsigned char" (alias uint8_t) für Aufgaben, bei denen es um > kleine Ganzzahlen geht. In der Praxis ists am sichersten, für Rechnerei <stdint.h> zu verwenden und char immer mit unsigned zu vereinbaren bzw. das dem Compiler schon klar zu machen. @Mario >die Warnung verschwindet nach dem zweiten mal compilieren und das Proggi >tut was es soll. Wie gesagt, beim zweiten Mal compilieren wird dein Quelltext garnicht mehr compiliert. Der Computer merkt, dass sich seit dem letzten Durchlauf am Quelltext nix verändert hat (Datum der letzten Änderung der Datei) und überspringt ihn einfach.
Datum: 28.04.2008 16:08
Sven Pauli wrote: > Jein. Die Bibel sagt, Char ist entweder gleich signed char _oder_ > gleich unsigned char, das ist maschinenabhängig. Wenn du C++ mit ins Boot nimmst, dann sind es doch wieder 3. Zwar ist auch da "char" technisch identisch mit einem der beiden anderen Typen und anfangs war das wie in C. Aber weil man damit sehr schlechte Erfahrung gemacht hat, sind das in C++ mittlerweile 3 formell inkompatible Typen. Ein "char *" ist auch dann zu einem "signed char *" imkompatibel, wenn beide technisch identisch sind. Zwar gilt dies nur für C++, es ist aber zu empfehlen, sich auch bei C einigermassen dran zu halten. > und char immer mit unsigned zu vereinbaren bzw. das dem Compiler schon > klar zu machen. Der Typ von "...." ist fest vorgegeben, und für die Interpretation der Library ist nur massgeblich, was bei deren Übersetzung angegeben war. Das setzt der Freiheit Grenzen.
Datum: 28.04.2008 16:25
Andreas Kaiser wrote: > Ein "char *" ist auch dann zu einem "signed char *" > imkompatibel, wenn beide technisch identisch sind. Ist in C inzwischen auch so, nur nicht ganz so strikt -- daher ist es eben kein Fehler, sondern nur eine Warnung. Ein Programm, das sich auf irgendeine signedness des Typs char verlässt, ist aber explizit nicht mehr portabel. Wenn einem die Portabilität egal ist, muss man sich natürlich nicht drum kümmern (dann könnte man die Warnung auch abschalten), aber ich behaupte hier mal, dass mehr als 95 % der Programmierer, die sich über die Warnung wundern, gar nicht wissen, welche Art Portabilitätsprobleme sie sich damit einhandeln könnten und daher gut beraten sind, die Warnung nicht zu ignorieren.
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
- Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel