main.c:1260: warning: passing argument 1 of 'strcpy' discards qualifiers from pointer target type
Ich sehe da kein Problem.
Gruß
Stefan
Didn't find your answer? Ask the community — no account required.
F
Frank Buss
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
C
Christian Zietz
Frank Buss schrieb:
Alternativ noch einmal überlegen, ob "mastercode" wirklich volatile sein muss.
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
C
Christian Zietz
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
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
H
Heinz Saathoff
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
M
Matthias Weißer
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?
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)
H
Heiko Nocon
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.
J
Joerg Wunsch
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. ;-)
J
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. ;-)
D
David Kastrup
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
E
Ernst Schwab
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;
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
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.