Hallo,
ich bekomme komische Warnungen von meinem XC8-Compiler:
1
ATCA_STATUSat_cmd_info(uint8_t*info_dest)
2
{
3
[...]
4
for([...])
5
{
6
info_dest[i]=i2c_receive();
7
}
8
[...]
9
}
1
warning: (1498) pointer (at_cmd_info@info_dest) in expression may have no targets
In dem XC8-Manual steht gar nichts zu einem Fehler/Warnung mit der Nr.
1498.
Ich denke der Compiler warnt mich davor, dass der Speicher hinter
`info_dest` zu klein ist. Aber warum? Jemand ne Idee?
Desweiteren gibt es auch Warnungen von Library-Code:
1
/opt/microchip/xc8/v1.45/sources/common/doprnt.c:538: warning: (373) implicit signed to unsigned conversion
2
/opt/microchip/xc8/v1.45/sources/common/doprnt.c:541: warning: (373) implicit signed to unsigned conversion
3
/opt/microchip/xc8/v1.45/sources/common/doprnt.c:757: warning: (373) implicit signed to unsigned conversion
4
/opt/microchip/xc8/v1.45/sources/common/doprnt.c:1316: warning: (373) implicit signed to unsigned conversion
5
/opt/microchip/xc8/v1.45/sources/common/doprnt.c:1317: warning: (373) implicit signed to unsigned conversion
6
/opt/microchip/xc8/v1.45/sources/common/doprnt.c:1500: warning: (373) implicit signed to unsigned conversion
7
/opt/microchip/xc8/v1.45/sources/common/doprnt.c:1524: warning: (373) implicit signed to unsigned conversion
Welchen Typ hat der Rückgabewert von i2c_receive?
Vermutlich ist er vorzeichenbehaftet. Da info_dest[i] vom Typ uint8_t
ist, können damit keine negativen Zahlen dargestellt werden, was zur
Warnung führt.
Wenn du sicher bist, dass durch die implizite Typkonvertierung keine
fehlerhaften Ergebnisse entstehen können, kannst du die Konvertierung
explizit machen und dadurch die Warnung beseitigen:
1
info_dest[i]=(uint8_t)i2c_receive();
Das alles gilt natürlich nur unter der Voraussetzung, dass i2c_receive()
tatsächlich vorzeichenbehaftet ist. Ist das nicht der Fall, liegt das
Problem woanders. Mit der Größe des Arrays hat das aber nichts zu tun.
Sorry für die späte Antwort.
Yalu X. schrieb:> Welchen Typ hat der Rückgabewert von i2c_receive?
i2c_receive hat 'uint8_t' als Rückgabewert.
Ich habe noch folgendes gefunden:
1
And it is basically stating that the pointer passed as argument "uint8_t *buffer" is being dereferenced and since there is no assignment of this pointer on the function it may has no valid address to be dereferenced for. So the compiler believes that before this function is called the pointer was assigned a valid address. Again, I am not worried about this warning.
Teo D. schrieb:> So ist wenigstens klar, das mit dem Pointer ein Array gemeint ist....
Ändert auch nichts :(.
Habe jetzt auch mal die Buffergröße mitgegeben und in der Schleife
abgebrochen, sollte der Buffer zu klein sein.
Ich schreib mal den Microchip Support an.
> ...
Kannst du ein minimales, vollständiges Beispiel geben, dass den Fehler
reproduziert? Also ohne unbekannte Macros (ATCA_STATUS), ohne unbekannte
Funktionen (i2c_receive), ohne die [...] und mit Compiler-Optionen.
Es werden sich hier vermutlich nicht viele Leute finden, die den XC8
installiert haben und dir trotz der wenigen Infos helfen wollen.
Toxic schrieb:> Ich wuerde einfach mal googeln:> http://www.microchip.com/forums/m1038697.aspx>> und mich bei XC8/PICs-Fragen direkt mit Microchip Forumusern> unterhalten.
Ge-googled habe ich, aber nach der konkreten Warnung und nicht
allgemein. Danke für den Link!
mh schrieb:> Kannst du ein minimales, vollständiges Beispiel geben, dass den Fehler> reproduziert?
Gerne.
1
uint8_tminimal_beispiel(uint8_t*buffer)
2
{
3
*buffer=0xFF;
4
return0;
5
}
führt zu
1
attec508a.c:162: warning: (1498) pointer (minimal_beispiel@buffer) in expression may have no targets
2
attec508a.c:162: warning: (759) expression generates no code
Ich denke den 'Generates no code' wird man los, wenn der Wert 0xFF nicht
ge-hardcoded wird. Spielt aber für das Beispiel keine Rolle.
Da fehlt mindestens nen include, oder du hast Fehlermeldungen/Warnungen
unterschlagen.
Aber vermutlich hast du ne ganze Menge andere Sachen unterschlagen:
XC8 schrieb:> attec508a.c:162
bei 5 Zeilen die du zeigst.
Gibt es die Warnung auch, wenn in der Datei nichts anderes steht außer
den 5 Zeilen + fehlendes inclcude?
mh schrieb:> Da fehlt mindestens nen include, oder du hast Fehlermeldungen/Warnungen> unterschlagen.
Jaaa. uint8_t ist halt kein Standarddatentyp, dazu muss stdint.h oder
inttypes.h inkludiert werden (ich vergesse immer welche der beiden es
ist).
Alternativ nimm halt einfach nur int. Geht genauso.
1
intminimal_beispiel(int*buffer)
2
{
3
*buffer=0xFF;
4
return0;
5
}
1
attec508a.c:155: warning: (1498) pointer (minimal_beispiel@buffer) in expression may have no targets
2
attec508a.c:155: warning: (759) expression generates no code
mh schrieb:> Aber vermutlich hast du ne ganze Menge andere Sachen unterschlagen:> XC8 schrieb:>> attec508a.c:162> bei 5 Zeilen die du zeigst.
Naja, ist halt ein Minimalbeispiel. Abgesehen davon ist doch erkennbar,
dass ich die ganze Funktion gepostet habe. Die anderen Funktionen in der
Datei sind für das Verhalten vollkommen irrelevant.
mh schrieb:> Gibt es die Warnung auch, wenn in der Datei nichts anderes steht außer> den 5 Zeilen + fehlendes inclcude?
Ja.
1
test.c:4: warning: (1498) pointer (minimal_beispiel@buffer) in expression may have no targets
2
test.c:4: warning: (759) expression generates no code
int minimal() {}
ist von extern sichtbar (da nicht static) und kann deshalb von anderen
Compilation-Units aufgerufen werden. Wie die das machen,weiß der
Compiler aber nicht, im Gegensatz zu Aufrufenaus der gerade übersetzten
Compilation Unit. Also sagt er zur Sicherheit "kann schief gehen".
Man kann sich natürlich darüber streiten, ob diese "keine Katze in der
Nicrowelle trocken"-Meldung wirklich hilft, aber zumindest kann man MC
deshalb nicht verklagen.
Leider haben "viele Warnungen" Konjunktur gegenüber "wenige Wichtige"
und es ist hat "echt hilfreich", wenn die eine Nadel-Warnung in dem
Haufen Warnung-Heu so stark heraus sticht.
Eventuell kann man dieses Feature des XC8 aber auch ausschalten.
XC8 schrieb:> ... Die anderen Funktionen in der> Datei sind für das Verhalten vollkommen irrelevant.
Du verstehst etwas nicht und Fragst in einem Forum nach Hilfe. Glaubst
du, dass du die richtige Person bist, um zu entscheiden wo oder was das
Problem ist?
Du solltest dir mal https://stackoverflow.com/help/mcve durchlesen und
für deine nächste Problembeschreibung zu Herzen nehmen.
XC8 schrieb:> mh schrieb:>> Gibt es die Warnung auch, wenn in der Datei nichts anderes steht außer>> den 5 Zeilen + fehlendes inclcude?>> Ja.
Dann fehlen jetzt noch die Compiler-Optionen
XC8 schrieb:> *buffer = 0xFF;
Hat so kein Ziel -> NULL.
Ruf diese Funktion mal korrekt auf oder initialisiere mal den Pointer
auf eine gültige Adresse.
Dann ist bei mir die Warnung auch weg.
Teo D. schrieb:> XC8 schrieb:>> *buffer = 0xFF;>> Hat so kein Ziel -> NULL.>> Ruf diese Funktion mal korrekt auf oder initialisiere mal den Pointer> auf eine gültige Adresse.> Dann ist bei mir die Warnung auch weg.
Das kann wohl kaum die Lösung sein oder wie soll man das bei
Bibliotheksfunktionen machen?
mh schrieb:> Teo D. schrieb:>> XC8 schrieb:>>> *buffer = 0xFF;>>>> Hat so kein Ziel -> NULL.>>>> Ruf diese Funktion mal korrekt auf oder initialisiere mal den Pointer>> auf eine gültige Adresse.>> Dann ist bei mir die Warnung auch weg.>> Das kann wohl kaum die Lösung sein oder wie soll man das bei> Bibliotheksfunktionen machen?
Wenn der Compiler gut ist, sollte er spätestens wenn eine Prüfung auf
ungleich NULL drin ist, mit der Warnung aufhören. Denn darum geht's ja
eigentlich:
"Achtung, du dereferenzierst einen Pointer, von dem ich nicht weiß, ob
er gültig ist"
mh schrieb:> Das kann wohl kaum die Lösung sein oder wie soll man das bei> Bibliotheksfunktionen machen?
'extern' dazu klöppeln?
Ist ja NUR ne Warnung, kein Error.
Carl D. schrieb:> Wenn der Compiler gut ist, sollte er spätestens wenn eine Prüfung auf> ungleich NULL drin ist, mit der Warnung aufhören. Denn darum geht's ja> eigentlich:> "Achtung, du dereferenzierst einen Pointer, von dem ich nicht weiß, ob> er gültig ist"
Wenn das tatsächlich der Grund ist und sich nicht ausschlaten lässt,
gehört der Compiler in den Müll.
Ich alleine entscheide wo und wann ich einen Pointer auf NULL prüfe. Und
ich ziehe vor dort zu prüfen, wo der Pointer NULL werden kann und nicht
da, wo ich ihn benutze.
mh schrieb:> Wenn das tatsächlich der Grund ist und sich nicht ausschlaten lässt,> gehört der Compiler in den Müll.Teo D. schrieb:> Ruf diese Funktion mal korrekt auf oder initialisiere mal den Pointer> auf eine gültige Adresse.Dann ist bei mir die Warnung auch weg
Teo D. schrieb:> 'extern' dazu klöppeln?
Was soll extern bringen?
Teo D. schrieb:> Ist ja NUR ne Warnung, kein Error.
Jede unsinnige Warnung, die nicht beseitigt werden kann lenkt von echten
Warnungen ab, und ist damit nicht zu akzeptieren. Was ist, wenn ich 30
Funktionen habe, die nen Pointer als Argument haben. Wie soll ich dann
die eine echte Warnung sehen?
mh schrieb:> Carl D. schrieb:>> Wenn der Compiler gut ist, sollte er spätestens wenn eine Prüfung auf>> ungleich NULL drin ist, mit der Warnung aufhören. Denn darum geht's ja>> eigentlich:>> "Achtung, du dereferenzierst einen Pointer, von dem ich nicht weiß, ob>> er gültig ist">> Wenn das tatsächlich der Grund ist und sich nicht ausschlaten lässt,> gehört der Compiler in den Müll.
;-)
Wenn stimmt, was weiter oben wohl getestet wurde, daß der XC8 die
Prüfung nicht erkennt, dann könnte das auch ein "haben wir auch" auf die
diversen Prüfungen, die clang und GCC drauf haben, sein.
> Ich alleine entscheide wo und wann ich einen Pointer auf NULL prüfe. Und> ich ziehe vor dort zu prüfen, wo der Pointer NULL werden kann und nicht> da, wo ich ihn benutze.
In einer Library wäre das aber nicht der beste Ansatz.
Vielleicht bist du aber nur zu jung und kannst Dinge, die Compiler für
dich erledigen (mangels Bedarf) noch nicht so richtig würdigen. Ich
schreibe zunehmend größere Programme, als ich sie noch komplett
überblicken könnte. Da ist man über Hilfe froh ;-)
Carl D. schrieb:> In einer Library wäre das aber nicht der beste Ansatz.
Ich sage nicht, dass es für jeden und alles der beste Ansatz ist. Für
meine Zwecke halte ich es für den besten Ansatz. Andere gewichten die
Argumente dafür und dagegen anders und kommen zu einem anderen Ergebnis.
Ich habe mal eine Funktion aus einer sehr bekannten Library
ausgewählt: memcpy. Ich zitiere aus der Beschreibung aus
http://en.cppreference.com/w/c/string/byte/memcpy, da ich zu Faul bin
sie aus dem Standard herauszusuchen:
1
The behavior is undefined if either dest or src is a null pointer.
Und tatsächlich weder glibc noch newlib prüfen in memcpy, ob einer der
Pointer NULL ist.
Es gibt also noch andere Personen, die der Meinung sind, dass es ein
geeigneter Ansatz ist.
mh schrieb:> Carl D. schrieb:>> In einer Library wäre das aber nicht der beste Ansatz.> Ich sage nicht, dass es für jeden und alles der beste Ansatz ist. Für> meine Zwecke halte ich es für den besten Ansatz. Andere gewichten die> Argumente dafür und dagegen anders und kommen zu einem anderen Ergebnis.>> Ich habe mal eine Funktion aus einer sehr bekannten Library> ausgewählt: memcpy. Ich zitiere aus der Beschreibung aus> http://en.cppreference.com/w/c/string/byte/memcpy, da ich zu Faul bin> sie aus dem Standard herauszusuchen:>
1
> The behavior is undefined if either dest or src is a null pointer.
2
>
>> Und tatsächlich weder glibc noch newlib prüfen in memcpy, ob einer der> Pointer NULL ist.>> Es gibt also noch andere Personen, die der Meinung sind, dass es ein> geeigneter Ansatz ist.
Vermutlich ist obiger Text schon ein paar Jährchen alt.
Und es ist ja nicht so, daß man Warnungen nicht ignorieren könnte, wenn
man weiß, was man tut, nur manchmal bemerkt man solche Sachen einfach
nicht und es ist immer besser das zur Compile-Zeit zu erfahren.
Und wie hatte mal einer in einem Vortrag (über C++) zu Compiletime
Exceptions in constexpr gesagt: die werden nicht ausgeliefert.
Carl D. schrieb:> Und es ist ja nicht so, daß man Warnungen nicht ignorieren könnte, wenn> man weiß, was man tut, nur manchmal bemerkt man solche Sachen einfach> nicht und es ist immer besser das zur Compile-Zeit zu erfahren.
Nur was macht man, wenn man dutzende dieser Warnungen hat, und die
echten Warnungen nicht mehr sofort sieht?
Ich hab nicht ohne Grund mehrfach nach den Compiler-Optionen gefragt.
mh schrieb:> Carl D. schrieb:>> Und es ist ja nicht so, daß man Warnungen nicht ignorieren könnte, wenn>> man weiß, was man tut, nur manchmal bemerkt man solche Sachen einfach>> nicht und es ist immer besser das zur Compile-Zeit zu erfahren.>> Nur was macht man, wenn man dutzende dieser Warnungen hat, und die> echten Warnungen nicht mehr sofort sieht?> Ich hab nicht ohne Grund mehrfach nach den Compiler-Optionen gefragt.
Ich hab ja nicht gesagt, daß mir dieser Compiler gut gefällt. Er warnt
vor etwas, dessen Beseitigung er nicht erkennt. Man kann die Warnungen
anscheinend nicht ausschalten, ...
Manchmal entscheidet man sich eben auch für (oder gegen) eine
Architektur, weil sie von brauchbaren (nicht) Compilern unterstützt
wird.
Und so wurde ich dann mit PIC nie warm. Ein Privileg, das ich mir bei
den kleinen Bastelrechnern daheim leisten kann, auf den dicken Hobeln
auf der Arbeit nicht.
Teo D. schrieb:> Teo D. schrieb:>> Ruf diese Funktion mal korrekt auf oder initialisiere mal den Pointer>> auf eine gültige Adresse.> Dann ist bei mir die Warnung auch weg
Wir reden aneinander vorbei.
Zeig mal bitte deinen Code.
Carl D. schrieb:> ist von extern sichtbar (da nicht static) und kann deshalb von anderen> Compilation-Units aufgerufen werden. Wie die das machen,weiß der> Compiler aber nicht, im Gegensatz zu Aufrufenaus der gerade übersetzten> Compilation Unit. Also sagt er zur Sicherheit "kann schief gehen".
Wie kann man eine Funktion denn falsch aufrufen? Wenn ich ein Argument
weglasse, schlägt die Kompilierung fehl. Zudem weiß der Compiler durch
die Prototypen (aus den Headern) wie die Funktion aufgerufen werden soll
(und das in jeder Compilation Unit).
XC8 schrieb:> Alternativ nimm halt einfach nur int. Geht genauso.> int minimal_beispiel(int *buffer)> {> *buffer = 0xFF;> return 0;> }
minimal_beispiel(0x100);
oder
> int minimal_beispiel(int *buffer)> {
buffer = 0x100;
> *buffer = 0xFF;> return 0;> }
Get doch NUR um:
Teo D. schrieb:> XC8 schrieb:>> test.c:4: warning: (1498) pointer (minimal_beispiel@buffer) in>> expression may have no targets
?
Danke!
Teo D. schrieb:>> Alternativ nimm halt einfach nur int. Geht genauso.>> int minimal_beispiel(int *buffer)>> {>> *buffer = 0xFF;>> return 0;>> }>> minimal_beispiel(0x100);
Ok, so klappt es bei mir auch.
Die Funktionen wurde bei mir noch gar nicht aufgerufen, dass hat der
Compiler wohl als Anlass genommen sich zu beschweren?!?
(Über die 'Function never called'-Warnung hinaus natürlich).
XC8 schrieb:> Compiler wohl als Anlass genommen sich zu beschweren?!?
Das is aber ne andere Warnung, die bleibt auch beim 2. Beispiel
erhalten.
XC8 schrieb:> attec508a.c:162: warning: (759) expression generates no code
Irgend was mit 'Wird nie aufgerufen/verwendet' könnte auch noch
auftauchen.
(mom nur aus der Erinnerung, läuft hier grad nicht)
Teo D. schrieb:> XC8 schrieb:>> Alternativ nimm halt einfach nur int. Geht genauso.>> int minimal_beispiel(int *buffer)>> {>> *buffer = 0xFF;>> return 0;>> }>> minimal_beispiel(0x100);Teo D. schrieb:>> int minimal_beispiel(int *buffer)>> {> buffer = 0x100;>> *buffer = 0xFF;>> return 0;>> }
Autsch! Ich hoffe der Compiler gibt bei den Beispielen echte Warnungen.
Sowas wie "assignment makes pointer from integer without a cast". Mal
davon abgesehen, dass das vermutlich undefined behaviour ist.
mh schrieb:> Autsch! Ich hoffe der Compiler gibt bei den Beispielen echte Warnungen.
Aber sowas von... :)
Darum gings aber nicht!
Du hast schon kariert das dies ein Beispiel ist, kein Programm!
Oller Krawallheini..... :P
XC8 schrieb:> Carl D. schrieb:>> ist von extern sichtbar (da nicht static) und kann deshalb von anderen>> Compilation-Units aufgerufen werden. Wie die das machen,weiß der>> Compiler aber nicht, im Gegensatz zu Aufrufenaus der gerade übersetzten>> Compilation Unit. Also sagt er zur Sicherheit "kann schief gehen".>> Wie kann man eine Funktion denn falsch aufrufen? Wenn ich ein Argument> weglasse, schlägt die Kompilierung fehl. Zudem weiß der Compiler durch> die Prototypen (aus den Headern) wie die Funktion aufgerufen werden soll> (und das in jeder Compilation Unit).
z.B.
1
minimal_beispiel(NULL);
Passiert das in einer anderen Compilation-Unit, dann weiß der Compiler
davon nichts und genau das sagt er.
Wie schon einmal geschrieben scheint er aber nicht schlau genug zu sein,
eine Prüfung auf !=NULL zu verstehen, deswegen ist das für mich nicht
einer der Besten seiner Art.