www.mikrocontroller.net

Forum: Compiler & IDEs GCC: Compiler-Fehlermeldung bei Übergabe an Pointer


Autor: Mario M. (mariom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: CHAR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Mario M. (mariom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.