Forum: Compiler & IDEs AVR: strcpy: differ in signedness


von Bill (Gast)


Lesenswert?

hi,

ich habe hier eine warnung die ich nicht verstehe.

warning: pointer targets in passing argument 1 of 'strcpy' differ in 
signedness.

sind doch beides unsigned char* ...!?

1
unsigned char tx_buffer[8];
2
3
(...)
4
5
uint8_t put_string(unsigned char * s) {
6
   strcpy(tx_buffer, s);
7
   (...)
8
}


Gruß,

Billibooooy

von (prx) A. K. (prx)


Lesenswert?

"char *" (strcpy) entspricht auf vielen Plattformen dem "signed char *".

von Max P. (eizo)


Lesenswert?

Das Problem kenne ich auch hat aber bisher nie zu Problemen geführt also 
kann man es ignorieren?!?

von Sven P. (Gast)


Lesenswert?

Kann man. Warum genau schreibst du denn überhaupt 'unsigned' vor das 
'char', wenn du Zeichen meinst?

Dem GCC kann man auch mitteilen, wie man denn das 'char' gerne hätte.

von holger (Gast)


Lesenswert?

>Das Problem kenne ich auch hat aber bisher nie zu Problemen geführt also
>kann man es ignorieren?!?

Oder casten, dann ist es auch weg:

   strcpy(tx_buffer, (char *)s);

von (prx) A. K. (prx)


Lesenswert?

Beide casten.

von Johannes M. (johnny-m)


Lesenswert?

char, unsigned char und signed char sind per Definition drei 
verschiedene Dinge. Und Textzeichen sind grundsätzlich weder signed 
noch unsigned, sondern einfach nur char.

von Peter (Gast)


Lesenswert?

wenn man nicht ewig nach einem speicher überschreiber suchen sollte 
würde ich eh noch ne prüfung einbauen oder memcpy verwenden

uint8_t put_string(unsigned char * s) {
   memcpy(tx_buffer, s, sizeof(tx_buffer)-1);

von (prx) A. K. (prx)


Lesenswert?

Johannes M. wrote:

> char, unsigned char und signed char sind per Definition /drei/
> verschiedene Dinge. Und Textzeichen sind grundsätzlich weder signed
> noch unsigned, sondern einfach nur char.

Auf ANSI C++ trifft dies so zu, aber auf C (89) meines Wissens nicht 
(auf das ursprüngliche Stroustrup C++ auch nicht).

von Sven P. (Gast)


Lesenswert?

A. K. wrote:
> Johannes M. wrote:
>
>> char, unsigned char und signed char sind per Definition /drei/
>> verschiedene Dinge. Und Textzeichen sind grundsätzlich weder signed
>> noch unsigned, sondern einfach nur char.
>
> Auf ANSI C++ trifft dies so zu, aber auf C (89) meines Wissens nicht
> (auf das ursprüngliche Stroustrup C++ auch nicht).

In ANSI-C (ohne ++) ist 'char' entweder 'signed char' oder 'unsigned 
char'.
Was ist denn ein 'char' in C++, wenns weder signed noch unsigned ist?

von (prx) A. K. (prx)


Lesenswert?

Für den Basistyp ist es natürlich schnuppe, da Integer-Typen ineinander 
konvertiert werden. Und "char" entweder ein Vorzeichen hat oder halt 
keins.

Von Bedeutung ist das jedoch bei C++ spezifischen Sprachelementen wie 
Overloading bei abgeleiteten Typen wie Pointern.

Da ist es ziemlich hilfreich, wenn "char *", "unsigned char *" und 
"signed char *" formal drei verschiedene Typen sind. Somit bei einem 
"abc" als Parameter immer die Variante "char *" gefragt ist, egal auf 
welcher Plattform. Bevor man dies so festlegte, landete man je nach 
Plattform mal hier, mal da, und oft bei einem Fehler.

von holger (Gast)


Lesenswert?

Also ich bin ja ein Depp was programmieren angeht.
Ich hab es nie richtig gelernt.
Bisher habe ich aber noch keinen Compiler
gesehen der ein char mit mehr als 8 Bit
interpretiert. Ist die ganze Diskussion
eventuell überflüssig?

von (prx) A. K. (prx)


Lesenswert?

Mit der Anzahl Bits hat das reinweg garnichts zu tun. Aber wo du schon 
dabei bist: In der Frühphase von C gab es eine 36-Bit Honeywell 6000 mit 
9 Bit chars.

Eher schon mit der Eigentümlichkeit der DEC PDP11 Architektur. Denn ohne 
deren seltsame Angewohnheit, Bytes automatisch mit Vorzeichen zu 
erweitern, wäre wohl nie jemand auf die Idee mit vorzeichenbehafteten 
Zeichen gekommen. Und da C (und Unix) historisch untrennbar mit der 
PDP11 verbunden sind ist da nichts mehr zu retten.

von Gast (Gast)


Lesenswert?

> Was ist denn ein 'char' in C++, wenns weder signed noch unsigned ist?

Damit war nicht gemeint, daß ein 'char' eine andere "Ausprägung" als 
signed oder unsigned haben kann. Vielmehr hängt es bei 'char' von der 
verwendeten Plattform und/oder dem verwendeten Compiler ab, ob es signed 
oder unsigned ist.

Das heißt, wenn man 'signed char' schreibt, dann bekommt man auch ein 
'signed char'. Schreibt man 'unsigned char', bekommt man auf jeden Fall 
ein 'unsigned char'. Schreibt man aber einfach nur 'char', dann hängt es 
von der Plattform/vom Compiler ab, ob man ein 'unsigned char' oder ein 
'signed char' bekommt.

Das ist auch genau das Problem, das der OP hat. strcpy() will als 
Argument ein 'char' haben, was auf der vom OP verwendeten Plattform 
offenbar ein 'signed char' ist, aber er übergibt nun ein 'unsigned 
char'.

Im Übrigen ist das nicht nur in C++, sondern auch in C so. Der 
nächstbeste ANSI- oder ISO-C-Standard beschreibt dies ausführlich.
(Die Standard selbst kosten eine Menge Geld, aber zumindest die Drafts 
kann man kostenlos runterladen; die reichen für die meisten Zwecke auch 
aus.)

von Simon K. (simon) Benutzerseite


Lesenswert?

Gast wrote:
>> Was ist denn ein 'char' in C++, wenns weder signed noch unsigned ist?

Unter C++ ist ein char ein char, ein unsigned char ist ein unsigned char 
und ein signed char ist ein signed char. Punkt!

Ein char* ist nicht zuweisungskompatibel zu signed char* oder unsigned 
char*, sondern NUR zu char.

Und char bedeutet character bedeutet Zeichen. Und deswegen sollte man 
den Datentypen char nur für Zeichen(ketten) benutzen. Punkt aus, und 
genau so macht man es, und genau so macht man es richtig. Unsigned char 
und signed char ist eigentlich nicht für Zeichen geeignet, da ein 
Zeichen keinerlei Vorzeichen haben kann.

von (prx) A. K. (prx)


Lesenswert?

Gast wrote:

> Schreibt man aber einfach nur 'char', dann hängt es
> von der Plattform/vom Compiler ab, ob man ein 'unsigned char' oder ein
> 'signed char' bekommt.

In ANSI C++ definitiv nicht. Probier es aus. Zwar wird der "char" 
entweder ein Vorzeichen haben oder keins, aber seine Adresse ist weder 
mit "signed char *" noch mit "unsigned char *" kompatibel.

So liefert GCC bei
1
void f1(signed char *);
2
void f2(unsigned char *);
3
void g(char c) { f1(&c); f2(&c); }
als C garkeine Fehlermeldung (ggf. Warnings wenn eigeschaltet), dafür 
als C++ gleich zwei.

von Simon K. (simon) Benutzerseite


Lesenswert?

1
  char* a;
2
  unsigned char* b;
3
  signed char* c;
4
  a = b;
5
  a = c;

Liefert zwei Warnings:
../Main.c:64: warning: pointer targets in assignment differ in 
signedness
../Main.c:65: warning: pointer targets in assignment differ in 
signedness

kompiliert mit avr-gcc im GNU99 Standard.
avr-gcc -Wall -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char 
-funsigned-bitfields -mmcu=atxmega128a1 -DF_CPU=32000000UL -MMD -MP 
-MF"Main.d" -MT"Main.d" -c -o"Main.o" "../Main.c"

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.