Hallo ihr coder Ich arbeite mich seit ein paar wochen in C ein und stelle fest das mein code verdammt viele Warnungen generiert. Hatte schnell festgestellt dass die es trotzdem läuft. Jetzt wollte ich aber gerne die Warnungen aus meinem Code enfernen oder vielleicht wenigstens abschalten. Grund: wenn ich denn dann mal wieder einen error produziert habe so muss ich mich erst durch mindestens 12.437 Zeilen Warungen wühlen um den eigendlichen Error zu finden. Hier eine Hitlist der häufigsten Warnungen: unübertroffen auf Platz 1: warning: passing arg 1 of `sprintf' discards qualifiers from pointer target type Code in dieser Zeile: sprintf(text, " Helligkeit: "); wird dicht gefolgt von diesem hier (Platz 2): warning: assignment discards qualifiers from pointer target type Code in dieser Zeile: (switch usw davor) case 0 : ptr = p_textV24;tmp2 = V_24;break; dann etwas abgeschlagen auf Platz 3: warning: assignment makes integer from pointer without a cast Code hier: if (sp[0x01] < 63) TempPos = " "; und dann nur einmal folgendes: warning: return type of 'main' is not `int' Würde mich freuen was von euch zu hören LG Markus
> Ich arbeite mich seit ein paar wochen in C ein und stelle fest das > mein code verdammt viele Warnungen generiert. Hatte schnell > festgestellt dass die es trotzdem läuft. Jetzt wollte ich aber > gerne die Warnungen aus meinem Code enfernen Gute Idee. > oder vielleicht wenigstens abschalten. Das bitte nur, wenn du wirklich verstehst, was die Warnung bedeutet und sicher weißt, daß sie harmos ist. > warning: passing arg 1 of `sprintf' discards qualifiers from > pointer target type >Code in dieser Zeile: sprintf(text, " > Helligkeit: "); Ohne Angabe der Argumenttypen kann man nur mutmaßen. Ist text vielleicht ein Zeiger auf const char oder volatile char? > warning: assignment discards qualifiers from pointer target type > Code in dieser Zeile: (switch usw davor) > case 0 : ptr = p_textV24;tmp2 = V_24;break; Hier stimmen vermutlich die Zeigertypen auch nicht. > warning: assignment makes integer from pointer without a cast > Code hier: if (sp[0x01] < 63) TempPos = " "; Sieht so aus als sei TempPos ein int. Warum benutzt du einen int, um die Adresse des Strings drin zu speichern? Dazu sind Zeiger da. > warning: return type of 'main' is not `int' Was ist daran unklar? Die C-Norm schreibt vor, daß main als Rückgabetyp int haben muß. Das hat die Funktion bei dir vermutlich nicht. Zugegeben, bei einem Mikrocontroller ist das recht nutzlos, aber es ist eben so in C. Schaden tut es ja auch nicht, also gib einen int zurück.
Hallo Markus, warnings sind der Aufruf des Compilers zur Überprüfung des Sourcecodes. Falls eine Warnung auftritt heißt das meist, dass warhscheinlich das Richtige (also das, was Du gewollt hast) gemacht wird. Warnings deuten aber auch meist auf unsauberen Code hin. An diesen Stellen sollte man dann entsprechende Casts oder andere Codeformulierungen verwenden, um das Ganze besser zu gestalten. Also warnings nicht ausschalten, lieber dementsprechend mehr im Sourcecode formulieren - das bedeutet i.A. nicht, dass am Ende das Kompilat größer wird. Beispiel :
1 | uint16_t ui16Dummy = 0x0000; |
2 | uint8_t pui8Dummy; |
3 | |
4 | pui8Dummy = ui16Dummy; |
führt wahrscheinlich dazu, dass der Compiler eine Warnung abgibt, weil eine Adresse von unit16_t in einen Pointer kopiert wird. Besser ist da
1 | uint16_t ui16Dummy = 0x0000; |
2 | uint8_t pui8Dummy; |
3 | |
4 | pui8Dummy = (uint8_t *)ui16Dummy; |
Das kompiliert nicht größer, jetzt weiß der Compiler aber genau, dass das was Du geschrieben hast auch dem entspricht, was Du gemeint hast. MfG, Daniel MfG, Daniel.
> warning: return type of 'main' is not `int' Beim AVR-GCC darf im main kein return stehen ! Es wird nämlich zu Beginn des main der Stackpointer neu gesetzt und damit kann das main nirgends hin zurückkehren. Laut ANSI-C ist main eine ganz normale Funktion, und kann sich daher auch selbst aufrufen. Aber das geht eben nicht im AVR-GCC !!! Das main muß also eine Endlosschleife ohne return beinhalten, dann wird nicht mehr gemeckert. Peter
> Beim AVR-GCC darf im main kein return stehen ! Quark. > Es wird nämlich zu Beginn des main der Stackpointer neu gesetzt und > damit kann das main nirgends hin zurückkehren. Doch. Das return von main() ist ja offziell eine Übergabe des Rückkehrwerts an die Funktion exit(). Der AVR-GCC weiß um seine Besonderheit des main(), und implementiert diese als Sprung in die Funktion exit(). Das Ganze hat natürlich nur dann einen Effekt, wenn man ein eigenes exit() vorsieht. Außerdem sollte exit() natürlich nirgendwohin zurückkehren wollen. ;-) > Laut ANSI-C ist main eine ganz normale Funktion, und kann sich daher > auch selbst aufrufen. Aber das geht eben nicht im AVR-GCC !!! Kein Grund zum Rumschreien. Das Einzige, was nicht funktioniert ist, dass man main() rekursiv aufruft. Aber ehrlich, wo hast du das im Realen Leben[tm] schon mal gesehen, dass jemand main() rekursiv aufruft? Ich kenne das bestenfalls vom IOCCC. Ganz davon abgesehen, ich glaube, die Umwandlung von main() in eine ,,ganz normale'' Funktion steht bei irgendeinem AVR-GCC-Entwickler sogar auf der Liste. > Das main muß also eine Endlosschleife ohne return beinhalten, dann > wird nicht mehr gemeckert. Es wird auch nicht gemeckert, wenn man das return dranschreibt, und falls davon eine Endlosschleife ist, erkennt der Optimizer das auch und eliminiert das return.
p.s.:
> Laut ANSI-C ist main eine ganz normale Funktion, ...
Ist es übrigens nicht. Erstens ist der Prototyp vorgeschrieben,
außerdem (das macht GCC übrigens nicht) soll beim Erreichen von
} in main() eine 0 zurückgegeben werden. Nur zwei Beispiele, warum
das keine ,,ganz normale'' Funktion sein kann.
> Erstens ist der Prototyp vorgeschrieben, Und? Trotzdem ist es eine ganz normale Funktion. > außerdem (das macht GCC übrigens nicht) soll beim Erreichen von > } in main() eine 0 zurückgegeben werden. Nur dann, wenn da auch ein "return 0;" steht. Du verwechselst es evtl. mit C++.
>> außerdem (das macht GCC übrigens nicht) soll beim Erreichen von >> } in main() eine 0 zurückgegeben werden. > Nur dann, wenn da auch ein "return 0;" steht. Du verwechselst es > evtl. mit C++. Nein. ISO/IEC 9899:1999: ``5.1.2.2.3 Program termination 1 If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0. [...]''
>Das main muß also eine Endlosschleife ohne return beinhalten, dann wird nicht mehr gemeckert. Muss nicht: In der WinAVR Anleitung steht, dass am Ende von main automatisch eine Endlosschleife eingebaut ist. Schreibt man also in ein Programm return, hat das diesselbe Wirkung wie eine Endlosschleife.
@Benedikt "Schreibt man also in ein Programm return, hat das diesselbe Wirkung wie eine Endlosschleife." ??? Also ehe ich ständig nachsehe, welche Extrasüppchen jeder einzelne Compiler kocht, schreib ich es doch lieber so hin, daß es portabel ist, also jeder Compiler es versteht. Bei einem "return" erwarte ich eigentlich, daß die Funktion immmer zum Aufrufer zurückkehrt und nicht irgendwelche Sperenzchen macht. Wenn das Main am Schluß steht, kann das Programm durch die leeren 0xFFFFs durchnudeln, bis es wieder bei 0x0000 ankommt, d.h. es sieht nur so aus, als ob eine Schleife gemacht wird. In der Regel beinhaltet aber das Main 2 Teile: 1. alle Initialisierungen (LCD, UART usw.) 2. die zyklische Abarbeitung aller Hauptprozesse Und das geht nur, wenn man explizit eine Hauptschleife hinschreibt. Wie sonst soll denn der Compiler erkennen, was einmalig und was zyklisch auszuführen ist ? Peter
> Bei einem "return" erwarte ich eigentlich, daß die Funktion immmer > zum Aufrufer zurückkehrt und nicht irgendwelche Sperenzchen macht. Genau das macht es doch. Zumindest das Äquivalent davon... Wer ist aber bitte der Aufrufer von main()? (Von rekursiven Aufrufen abgesehen, wie schon geschrieben, daran wird auch noch gearbeitet, aber das ist auch alles andere als wirklich ein wichtiges Feature.) Wenn main() zurückkehrt, wird halt ein exit() aufgerufen. Genau das schreibt der C-Standard vor, und genau das macht der Compiler. Das exit() macht dann per default eine Endlosschleife, aber du kannst dir dafür auch gern was anderes einfallen lassen. Eine vernünftige Applikation hat natürlich trotzdem ihre eigene Hauptschleife, keine Frage (und wenn der Compiler feststellt, dass das main() gar nicht zurückkehren kann, kann er sich auch das Weiterreichen an exit() sparen).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.