WINAVR, warum bekomme ich hier ein Warning

Hallo,

wieso bekomme ich in Winavr bei der folgenden Formulierung in der Zeile mit dem strcpy() ein Warning?

------------------ snip ---------------------------- ... volatile char mastercode[11]; ... strcpy(mastercode,"xxx"); ...

------------------ snip ----------------------------

Die Meldung lautet:

main.c:1260: warning: passing argument 1 of 'strcpy' discards qualifiers from pointer target type

Ich sehe da kein Problem.

Gruß

Stefan

Reply to
Stefan
Loading thread data ...

Schonmal von Google deine Warnung suchen lassen? Kurzfassung: strcpy erwartet char*, du übergibst aber volatile char*. So sollte es ohne Warnung gehen: strcpy((char*)mastercode, "xxx")

--
Frank Buss, http://www.frank-buss.de
piano and more: http://www.youtube.com/user/frankbuss
Reply to
Frank Buss

Frank Buss schrieb:

Alternativ noch einmal überlegen, ob "mastercode" wirklich volatile sein muss.

Christian

--
Christian Zietz  -  CHZ-Soft  -  czietz (at) gmx.net
WWW: http://www.chzsoft.de/
PGP/GnuPG-Key-ID: 0x6DA025CA
Reply to
Christian Zietz

Am 25.09.2011 14:20, schrieb Christian Zietz:

Guter Tip, muss ich mal abchecken...

andererseits: warning ist ja eigentlich kein Problem

Gruß

Stefan

Reply to
Stefan

solange bis die Liste der Warnungen so groß ist, daß die neue und wirklich bedenkliche Warnung nicht mehr auffällt.

Ich eliminiere grundsätzlich alle Warnungen.

--
Gruß, Raimund
Mein Pfotoalbum 
Mail ohne Anhang an  wird gelesen. Im Impressum der Homepage
findet sich immer eine länger gültige Adresse.
Reply to
Raimund Nisius

Am 25.09.2011 17:56, schrieb Raimund Nisius:

Stimmt schon. Ich versuche das auch. Im Moment habe ich in dem Projekt auch nur noch ca. 5 Warnings übrig.

Einmal das hier:

------------------------------------------------------- void LCD_printtxtfromflash(char line, char *FlashSTR) { uint8_t c=0; do { c = pgm_read_byte_far(FlashSTR++); if (c) LCD_printchar(line++,c); } while (c); }

-------------------------------------------------------

da kommt in der Zeile mit dem pgm_read_byte_far(): ./lcd.h:261: warning: cast from pointer to integer of different size

Und dann das hier:

------------------------------------------------------------------------- char i2c_readrandombyte_EEPROM(char devadr,uint16_t adr,char stop) { uint8_t ah,al,*adresse;

adresse = &adr; al = *adresse++; ah = *adresse; ...

--------------------------------------------------------------------------

Da kommt in der Zeile: adresse = &adr; ./i2c.h:348: warning: assignment from incompatible pointer type

Das scheint aber ein bekanntes Problem zu sein.

Gruß

Stefan

Reply to
Stefan

Stefan schrieb:

pgm_read_byte_far erwartet die Adresse wohl als Integer des Typs uint32_t und nicht als Pointer, der zudem bei Dir vermutlich nur 16 Bit groß ist. Wenn das an der Stelle trotzdem seine Richtigkeit hat, kannst Du die Meldung mit einem expliziten Typecast loswerden.

Vor allem hat der Compiler recht. Du weist einem Pointer auf uint8_t die Adresse eines uint16_t zu. Wenn Du nur Low- und Highbyte des

16-Bit-Integers haben willst, warum nutzt Du dann nicht die Operatoren

Christian

--
Christian Zietz  -  CHZ-Soft  -  czietz (at) gmx.net
WWW: http://www.chzsoft.de/
PGP/GnuPG-Key-ID: 0x6DA025CA
Reply to
Christian Zietz

Am 25.09.2011 18:25, schrieb Christian Zietz:

Genau das ist der Punkt. Hab das auch schon im Web gefunden, aber noch nicht ausprobiert.

Der Satz bezog sich eigentlich auf die Sache mit dem pgm_read_byte_far. Ist hier irgendwie verrutscht.

Klar. Kann man machen, wäre auch kein Problem. Ich wollte eine Lösung, die ein paar Bytes spart. Ist vieleicht nicht sinnvoll ;-)

Ich hab das jetzt so gelöst:

-------------------------------------- char ah,al; //,*adresse;

union word_byte { struct { uint8_t lo; uint8_t hi; } byte; unsigned short word; } ad;

ad.word = adr; al = ad.byte.lo; ah = ad.byte.hi; ...

--------------------------------------

aber du hast wohl recht,

al = adr / 256; ah = adr % 256;

kommt aufs selbe raus.

Gruß

Stefan

Reply to
Stefan

Stefan schrieb...

Das w=FCrde ich, gerade bei Anf=E4ngern in C, nicht so sehen. Es gibt=20 gen=FCgend Fallen, die C einem Anf=E4nger stellt und auf die der Compiler= =20 hoffentlich mit einer Warnung reagiert. Gerne gemachte Fahler: if(x =3D y) ...; // warnung: Zuweisung in if-Bedingung

char ch =3D 129; int x =3D ch; // welchen Wert hat x?=20

- Heinz

Reply to
Heinz Saathoff

Am 26.09.2011 14:06, schrieb Heinz Saathoff:

Da sollte der Compiler aber warnen.

Kommt darauf an. Ist bei dir char signed oder unsigned?

--
Matthias Weißer
matthias@matwei.de
http://www.matwei.de
Reply to
Matthias Weißer

Am 26.09.2011 14:06, schrieb Heinz Saathoff:

Ich habe mir angewöhnt, gcc nur noch mit -Wall -Werror aufzurufen.

Das zwingt einen dazu, bspw. casts explizit hizuschreiben. Das ist dann eine gute Gelegenheit, sich bewußt zu machen, was man damit macht.

Und für die Fälle, in denen der Compiler nicht erkennen kann, daß eine Variable aufgrund des Programmablaufs auf jeden Fall initialisiert wird, gibt es ja die bekannten

foo=0; /* Keep Compiler happy */

Konstrukte.

Falk

--
Boygroup sucht neuen Sänger (m/w)
Reply to
Falk Willberg

Aber selbst solche Warnungen sind berechtigt, denn sie zeigen, daß irgendwas an der Programmstruktur nicht der reinen Lehre entspricht.

Besser als dieses foo=0 ist es, die Programmstruktur zu ändern, bis eben das foo=0 nicht mehr nötig ist. I.d.R. läuft es eigentlich fast immer darauf hinaus, daß man nur eine Funktion in zwei zerlegen müßte.

Reply to
Heiko Nocon

Stefan schrieb:

Wenn alles bislang funktioniert hat, obwohl strcpy() das volatile ohnehin verworfen hat, dann ist das ein gutes Zeichen, dass dieses überflüssig war.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Stefan schrieb:

"Never start optimizing before you have profiled it."

Die Zeiten, in denen man mit "smartem" C-Code auch zwangsläufig "ein paar Bytes sparen" konnte, sind mittlerweile vorbei. Sofern du dich nicht davon überzeugt hast, dass der generierte Code durch dein Zutun wirklich kleiner geworden ist, solltest du es einfach erstmal so leserlich wie möglich hinschreiben.

Beispiel aus der Praxis, gerade erst vor paar Tagen gehabt. Der Zählerwert eines 16-bit-Zählers soll so manipuliert werden, dass nach einer bestimmten Zeit ein Überlauf erfolgt. Das heißt, man muss das Komplement des gewünschten Timeouts da hineinladen. Komplement ist eine Negation, also sah der Code so aus:

... uint16_t timeout;

TCNT1 = (uint16_t)-timeout;

Funktioniert. Nun kam eine neue Version des IAR-Compilers (für den der Code auch da ist) daher und warnte darüber, dass hier ein unäres Minus auf eine vorzeichenlose Zahl angewendet wird. Hat er natürlich irgendwie Recht. Also hin und her gecastet:

TCNT1 = (uint16_t)(-((int16_t)timeout));

Sieht schrecklich aus, geht aber ohne Warnungen durch.

Aber Moment mal, was eigentlich gewollt war, war doch nur:

TCNT1 = 65536ul - timeout;

Das drückt eigentlich ziemlich genau das aus, was der Programmierer damit erreichen will: die Differenz zum Überlaufwert von 65536 soll ermittelt und da hinein geschrieben werden.

Was soll ich sagen: die letzte Formulierung erzeugt exakt den gleichen Code (trotz der formalen Berechnung als 32-bit-Datentyp), und sie läuft auch ohne Warnungen (sowohl GCC als auch IAR) durch.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

schrieb:

Das ist das Holz, aus dem Sicherheitsbeauftragte geschnitzt werden. Fehlende volatile-Deklarationen führen im Problemfall typischerweise zu selten auftretenden nicht reproduzierbaren Fehlern und Abstürzen sowie nicht aufzuspürenden Heisenbugs.

Anekdotische Beweisführung ist in diesem Fall eine Riesendummheit. Selbst wenn auf dem aktuellen System 100% funktionieren, kann das mit der nächsten Compilerversion, dem nächsten Prozessor, einem weiteren Core, einer anderen Cacheline-size etc etc schon wieder vorbei sein, und dann ist es verdammt schwer rauszufinden, was eigentlich los ist.

--
David Kastrup
Reply to
David Kastrup

Joerg Wunsch schrieb:

ACK !!11elf

Bezogen auf die Frage des OP nochmal eine kurze Darstellung, was der frei erhältliche GCC in Erscheinungsform des WinAVR aus den verschiedenen erdenklichen Formulierungen macht:

void hilo1(unsigned short adr) { union word_byte { struct { uint8_t lo; uint8_t hi; } byte; unsigned short word; } ad;

ad.word = adr; lowbyte = ad.byte.lo; hibyte = ad.byte.hi;

// hilo1: // 0000 8093 0000 sts lowbyte,r24 // 0004 9093 0000 sts hibyte,r25 // 0008 0895 ret }

char hilo2(unsigned short adr) { unsigned char* adresse;

adresse = &adr; lowbyte = *adresse++; hibyte = *adresse; // hilo2: // 000a DF93 push r29 // 000c CF93 push r28 // 000e 00D0 rcall . // 0010 CDB7 in r28,__SP_L__ // 0012 DEB7 in r29,__SP_H__ // 0014 9A83 std Y+2,r25 // 0016 8983 std Y+1,r24 // 0018 8093 0000 sts lowbyte,r24 // 001c 8A81 ldd r24,Y+2 // 001e 8093 0000 sts hibyte,r24 // 0022 0F90 pop __tmp_reg__ // 0024 0F90 pop __tmp_reg__ // 0026 CF91 pop r28 // 0028 DF91 pop r29 // 002a 0895 ret }

void hilo3(unsigned short adr) { lowbyte = adr & 0xFF; hibyte = adr >> 8; hilo3: // 002c 8093 0000 sts lowbyte,r24 // 0030 9093 0000 sts hibyte,r25 // 0034 0895 ret }

void hilo4(unsigned short adr) { lowbyte = adr % 256; hibyte = adr / 256; // 0036 8093 0000 sts lowbyte,r24 // 003a 9093 0000 sts hibyte,r25 // 003e 0895 ret }

Variante hilo1 und hilo2 sind _nicht_ portabel, und die nichtportable Variante hilo2 erzeugt mit dem verzweifelten Versuch, es besser zu können als der Compiler, den schlechtesten Code.

Die einzigen für mich akzeptablen Formulierungen sind portable, also von den genannten hilo3 und hilo4, wobei bei hilo4 die gefahr besteht, dass ein 'dummer' Compiler plötzlich Divisionen in den Code einfügt.

Meine Empfehlung (wie auch schon im Posting von Christian Zietz genannt): Man verwende einfach nur '&' und '>>' (hilo3) und überlasse das Nachdenken über effiziente Codierung dem Compiler, der macht das schon.

Gruß Ernst

Reply to
Ernst Schwab

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.