mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik wie bekomme ich folgende warnings weg?


Autor: Samuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich bekomme mit dem KEIL Compiler für folgende Codeteile folgende 
Fehlermeldung und weiss nicht wie ich diese wegbekomme. kan mir jemand 
helfen:

u16 param1= 1300;



if(param1>= 0 && param1<=4095)
{
......
......
......
}

D:\.....\test.c(444): warning:  #186-D: pointless comparison of unsigned 
integer with zero


/*--------------------------------------------------------------------*/
sprintf((c08*)str_snd_sci_one, "\n\n\c param2=%d\n\0", param2);

D:\.....\test.c(1052): warning:  #192-D: unrecognized character escape 
sequence



/*--------------------------------------------------------------------*/

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel wrote:
> u16 param1= 1300;
>
> if(param1>= 0 && param1<=4095)
> {
> ......
> ......
> ......
> }

> D:\.....\test.c(444): warning:  #186-D: pointless comparison of unsigned
> integer with zero
Sinnloser Vergleich einer vorzeichenlosen Zahl mit Null.
param1>= 0 mit param1 als u16 wird immer größer oder gleich 0 sein.

> sprintf((c08*)str_snd_sci_one, "\n\n\c param2=%d\n\0", param2);
>
> D:\.....\test.c(1052): warning:  #192-D: unrecognized character escape
> sequence
'\c' gibts nicht.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> if(param1>= 0 && param1<=4095)

if(param1<=4095)

Und was soll "\c" sein? Das abschliessende "\0" ist überflüssig, das 
hängt der Compiler sowieso schon dran.

Und ich will mal hoffen, dass "param2" ein Vorzeichen hat, denn sonst 
wäre "%d" falsch.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Garnicht! Der Kompiler warnt Dich, weil ein unsigned int immer 
grösser-gleich Null ist...  Bist Du sicher, das es richtig ist, was Du 
da tust?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
> pointless comparison of unsigned integer with zero

Das mal auf Deutsch übersetzen:

sinnloser Vergleich eines unsigned integer mit 0

Wie lautet deine Zeile?
if(param1>= 0 && param1<=4095)

Aha, der Compiler will dir offenbar mitteilen, dass param1>=0 ein 
sinnloser Vergleich ist. Warum?
Welchen Datentyp hat param1? Das ist ein u16, also wohl ein unsigned 
int.
Und was ist das Charakteristikum eines unsigned Typen?
Er hat kein Vorzeichen.
Und das bedeutet was?
Er ist per Definition immer positiv, also immer größer oder gleich 0.

Autor: Praxisstudent (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe gerade das gleiche Problem. leider habe ich meinen Code aus 
diesem Artikel:

http://www.mikrocontroller.net/articles/Festkommaarithmetik
#include <stdint.h>
/*
 
Funktion zur Umwandlung einer vorzeichenlosen 32 Bit Zahl in einen String
 
*/
 
void my_uitoa(uint32_t zahl, char* string) {
  int8_t i;                             // schleifenzähler
 
  string[10]='\0';                       // String Terminator
  for(i=9; i>=0; i--) {
    string[i]=(zahl % 10) +'0';         // Modulo rechnen, dann den ASCII-Code von '0' addieren
    zahl /= 10;
  }
}

und es kommt auch der oben beschriebene Fehler. Kann jemand den Artikel 
verbessern wenn er so falsch ist?

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Praxisstudent schrieb:
> und es kommt auch der oben beschriebene Fehler

in welcher Zeile kommt denn der Fehler?

Autor: Praxisstudent (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der for-Schleife. kann ich diese irgendwie umschreiben?
zb
string[10]='\0';                       // String Terminator
  for(i=10; i>=1; i--) {
    i--;
    string[i]=(zahl % 10) +'0';         // Modulo rechnen, dann den ..
    zahl /= 10;
  }

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Praxisstudent schrieb:
> In der for-Schleife. kann

geht es noch genauer? Es muss doch eine Konkrete Zeile da stehen.

Autor: UV (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Praxisstudent schrieb:
> Ich habe gerade das gleiche Problem. leider habe ich meinen Code aus
> diesem Artikel:

> und es kommt auch der oben beschriebene Fehler. Kann jemand den Artikel
> verbessern wenn er so falsch ist?

Aha. Es gibt oben aber keinen Fehler sondern nur zwei Warnings. Und wo 
genau schreibst du auch nicht. Schulterzuck

Autor: Praxisstudent (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
und beim warning steht dann:
#188-D pointless comparison of unsigned integer with zero

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Praxisstudent schrieb:
> und beim warning steht dann:

warum steht da auf einmal uint8_t ???? Oben schreibst du etwas von
int8_t i;  

Wie sollen wir helfen, wenn sie der code ständig ändert?

Autor: Herbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Praxisstudent schrieb:
> und beim warning steht dann:
> #188-D pointless comparison of unsigned integer with zero

Du hast den falschen Datentyp abgeschrieben. Im obrigen Code ist i ein 
int_8 (vorzeichenbehaftet), in deinem Screenshot ist es ein uint_8 
(nicht vorzeichenbehaftet).

Autor: Praxisstudent (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Ich geh mich mal schnell vergraben. Danke.

Autor: W.A. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Praxisstudent schrieb:
> Kann jemand den Artikel verbessern wenn er so falsch ist?

Warum sollte es falsch sein, in der Abbruchbedingung ein ">=" stehen zu 
haben. Das ist kein Fehler und du bekommst auch keiner FEHLER-Meldung.

Statt "i>=0" könntest du natürlich ein völlig sinnentstellendes "i!=255" 
schreiben.

Autor: Herbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.A. schrieb:
> Statt "i>=0" könntest du natürlich ein völlig sinnentstellendes "i!=255"
> schreiben.

Dabei würde sich jeder tot Programmierer augenblicklich im Grab umdrehen 
und die lebende Fraktion sich sofort übergeben.

Autor: M. Köhler (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Praxisstudent schrieb:
> und beim warning steht dann:
> #188-D pointless comparison of unsigned integer with zero

Das gleiche Problem wie im Startpost: Die For-Schleife soll solange 
laufen, solange i größer oder gleich 0 ist. Da i aber als Unsigned Int 
definiert wird i immer größer oder gleich 0 sein, der Vergleich der 
For-Schleife entbehrt jeder Logik. Der Compiler warnt zurecht davor. 
Wenn man bis 0 runter zählen will sollte man als Bedingung der 
For-Schleife fragen, ob i nicht gleich 0 ist, also:
uint8_t i;
...
for( i = 9; i != 0; i--){
  //do anything
}
...

: Bearbeitet durch User
Autor: moeb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

was generelles:

1. Wenn man Integer ohne Vorzeichen mit Kostanten vergleicht, dann 
sollte man das immer in der Form tun

if (u8ParamX < 200u)
...

Du teilst dem Compiler mit, dass sowohl die Konstante als auch die 
Variable vom gleichen Typ (vorzeichenlos) sind, dann gibt es auch keinen 
Ärger.

2. Wenn man eine vorzeichenlose Zahl auf kleiner als 0 vergleicht, dann 
ist das wirklich pointless, da die Zahl ja niemals kleiner als Null sein 
kann und "größer/gleich Null" ist dann genauso immer wahr... ;)

Beste Grüße
das moeb

PS
Es gibt Leute, die machen das noch etwas anders:
if (200u == u8ParamX)

Vorteil: Wenn man das zweite Gleichheitszeichen vergisst, dann hast du 
keine Zuweisung, sondern unkompilierbaren Code...
Nachteil: Man muss bei Vergleichen einmal um die Ecke denken.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> Wenn man bis 0 runter zählen will sollte man als Bedingung der
> For-Schleife fragen, ob i nicht gleich 0 ist, also:
> uint8_t i;
> ...
> for( i = 9; i != 0; i--){
>   //do anything
> }
> ...

Dann wird der Fall i == 0 aber nicht mehr durchlaufen.

Daher ist das kein gleichwertiger Ersatz zu:
int8_t i;

for( i = 9; i >= 0; i--){
    //do anything
}

: Bearbeitet durch Moderator
Autor: M. Köhler (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moeb schrieb:
> Vorteil: Wenn man das zweite Gleichheitszeichen vergisst, dann hast du
> keine Zuweisung, sondern unkompilierbaren Code...

Andersrum wird ein Schuh draus: Wenn man ein Gleichheitszeichen vergisst 
hat man in der Bedingung einen Zuweisung und das ist nicht erlaubt, 
führt also unausweichlich zum Error.

Frank M. schrieb:
> Dann wird der Fall i == 0 aber nicht mehr durchlaufen.

Stimmt, aber das lässt sich anpassen, z. B. so:
int8_t i;

for( i = 10; i != 0; --i){
    //do anything
}
;)

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> Andersrum wird ein Schuh draus: Wenn man ein Gleichheitszeichen vergisst
> hat man in der Bedingung einen Zuweisung und das ist nicht erlaubt,
> führt also unausweichlich zum Error.

wer sagt das?

Warum sollte eine Zuweisung nicht erlaubt sein?
int i;
if ( i = GetValue() ) {
}

ist zulässig und auch sinnvoll

Autor: Daniel Abrecht (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch einige Varianten:
for( uint8_t i = 10; i-- != 0; ){
for( uint8_t i = 10; i--; ){
for( uint8_t i = 9; ~i; i-- ){

: Bearbeitet durch User
Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> Stimmt, aber das lässt sich anpassen, z. B. so:
> int8_t i;
>
> for( i = 10; i != 0; --i){
>     //do anything
> }


Aber nur, wenn die Laufvariable i innerhalb des Blocks nicht verwendet 
wird. Sonst müssen alle Vorkommnisse innerhalb des Blocks von i auf i-1 
geändert werden.

Daher ist Dein Vorschlag keine allgemeingültige Alternative ;-)

Autor: moeb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter II schrieb:
> M. K. schrieb:
>> Andersrum wird ein Schuh draus: Wenn man ein Gleichheitszeichen vergisst
>> hat man in der Bedingung einen Zuweisung und das ist nicht erlaubt,
>> führt also unausweichlich zum Error.
>
> wer sagt das?
>
> Warum sollte eine Zuweisung nicht erlaubt sein?
> int i;
> if ( i = GetValue() ) {
> }
>
> ist zulässig und auch sinnvoll

Absolut!

Autor: M. Köhler (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter II schrieb:
> ...
>
> Warum sollte eine Zuweisung nicht erlaubt sein?
>
>
> int i;
> if ( i = GetValue() ) {
> }
> 
>
> ist zulässig und auch sinnvoll

OK, ich hatte -Werror an, es wirft bei mir eine Warnung. Warum das aber 
Sinnvoll sein soll sehe ich ehrlich gesagt nicht.

Daniel A. schrieb:
> Noch einige Varianten:

Hab was am Auge: Wo sind denn da Zuweisungen in der Bedingung? Ich 
sehe nur Zuweisungen in der Initialisierung

Frank M. schrieb:
> Aber nur, wenn die Laufvariable i innerhalb des Blocks nicht verwendet
> wird. Sonst müssen alle Vorkommnisse innerhalb des Blocks von i auf i-1
> geändert werden.
>
> Daher ist Dein Vorschlag keine allgemeingültige Alternative ;-)

Hab ich das behauptet, dass es eine allgemeingültige Alternative ist? 
Nein, natürlich nicht. Man könnte ja auch einen while-Schleife oder eine 
do-while-Schleife benutzen. Und dass man den Schleifenblock anpassen 
muss sollte doch auch klar sein. Auch gegangen wäre:
uint8_t i;
...
for( i = 9; i != 0; i--){
  //do anything
}
//do same as for-loop with i=0
...

Man muss es halt so aufbauen, dass es auf das Problem passt, dass man 
hat.

: Bearbeitet durch User
Autor: Klaus H. (klummel69)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel A. schrieb:
> for( uint8_t i = 9; ~i; i-- ){

Ahhh, bring unsere Anfänger auf keine falschen Ideen.
Das funktioniert definitiv nicht! Die Abbruchbedingung ist immer false.

Ich lass euch mal Knobeln...

Autor: moeb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> Peter II schrieb:
>> ...
>>
>> Warum sollte eine Zuweisung nicht erlaubt sein?
>>
>>> int i;
>> if ( i = GetValue() ) {
>> }
>> >
>> ist zulässig und auch sinnvoll
>
> OK, ich hatte -Werror an, es wirft bei mir eine Warnung. Warum das aber
> Sinnvoll sein soll sehe ich ehrlich gesagt nicht.

Falls die aufgerufene Funktion eine Fehlerbehandlung durchführt und im 
Fehlerfall Null zurück gibt, dann wäre das legitim. Aber nur bei sehr 
guter Kommentierung.

Ein expizites Abfangen von Fehlern würde ich aber in jedem Fall 
vorziehen.

Autor: Student (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Also das stimmt ja nicht so ganz:
int i;
if ( i = GetValue() ) {
}

Es ging ja um Konstanten.
Ich habe zwar gerade keinen Compiler an, aber:
if (200u = GetValue()) {}

Sollte definitiv nicht Compilen.
Und die Message war auch: Hier hat man nicht einen fiesen Laufzeitfehler 
den man nur durch Debugging irgendwann findet, sondern man wird gleich 
in die richtige Zeile gelotzt.

Ähnlich dem ist auch sowas wie:
if ("".equals(str)) {}

In Java, um eine NPE für null-Strings zu verhindern. Daran musste ich 
mich aber auch erst gewöhnen.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> OK, ich hatte -Werror an, es wirft bei mir eine Warnung. Warum das aber
> Sinnvoll sein soll sehe ich ehrlich gesagt nicht.

Schon einige der ersten Mini-Progrämmchen im Kernighan-Ritchie zeigt, 
dass so etwas sogar sehr sinnvoll ist:
  while ((c = getchar ()) != EOF)
  {
      putchar ();
  }

Bei der Zuweisung in Peters Beispiel konnte der Vergleich (!= EOF) 
entfallen, da hier gegen 0 geprüft wurde. Sowas ist das tägliche Brot 
des C-Programmierers.

M. K. schrieb:
> Hab ich das behauptet, dass es eine allgemeingültige Alternative ist?

Immerhin hast Du danach einen allgemeingültigen Block mit Kommentar "do 
anything here" hinterlassen ;-)

Aber selbst wenn er nicht allgemeingültig gedacht war: Gehen wir nochmal 
auf das Programm von Praxisstudent zurück:

Im for-Block steht da
    string[i] = ....

und von daher ist Dein Vorschlag auch nicht gültig.

Btw: Du hattest sowieso int8_t verwendet. Da muss an den Parametern für 
for() genau gar nichts geändert werden.

Autor: moeb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Student schrieb:
> Also das stimmt ja nicht so ganz:int i;
> if ( i = GetValue() ) {
> }
>
> Es ging ja um Konstanten.
> Ich habe zwar gerade keinen Compiler an, aber:if (200u = GetValue()) {}
>
> Sollte definitiv nicht Compilen.
> Und die Message war auch: Hier hat man nicht einen fiesen Laufzeitfehler
> den man nur durch Debugging irgendwann findet, sondern man wird gleich
> in die richtige Zeile gelotzt.

Ja, du hast Recht. Wir haben ein wenig aneinandervorbeidiskutiert ;)

Autor: M. Köhler (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Schon einige der ersten Mini-Progrämmchen im Kernighan-Ritchie zeigt,
> dass so etwas sogar sehr sinnvoll ist:  while ((c = getchar ()) != EOF)
>   {
>       putchar ();
>   }

Das ist keine Zuweisung in der Bedingung. Die Bedingung lautet hier 
nämlich:
 c != EOF 

zuvor wird die Anweisung
 c = getchar()

ausgeführt.

Frank M. schrieb:
> und von daher ist Dein Vorschlag auch nicht gültig.

Und wo habe ich geschrieben, dass das eine fertig Lösung für das Problem 
ist? Ich hab echt was am Auge, gehe gleich mal zum Arzt.

Frank M. schrieb:
> Du hattest sowieso int8_t verwendet.

Nur weil ich deinen Beitrag kopiert hatte. Schau noch mal in meinen 
Vorschlag genau rein, und zwar den ersten den du bemängelt hast. ;)

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> Das ist keine Zuweisung in der Bedingung.

Doch.

Genauso, wie Peters
   if ( i = GetValue() ) {
eine Zuweisung in der Bedingung ist. Um die Compiler-Warnings 
wegzubekommen, muss Peter die Zeile nur richtig ausschreiben:
   if ( (i = GetValue()) != 0) {

Dann ist die Warnung weg. Aber beide Formulierungen sind absolut 
äquivalent, die von Peter ist lediglich eine Abkürzende Schreibweise, wo 
aber der Compiler nicht mehr sicher sein kann, dass Peter sich 
verschrieben hat mit dem einfachen Gleichheitszeichen. Daher die 
Warnung.

Und wenn Du nun schaust, sieht
   if ( (i = GetValue()) != 0) {

von der Form her verdammt ähnlich aus zu:
   if ( (c = getchar()) != EOF) {

Und damit für mich EOD. Lern erstmal C.

: Bearbeitet durch Moderator
Autor: Daniel Abrecht (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus H. schrieb:
> Daniel A. schrieb:
>> for( uint8_t i = 9; ~i; i-- ){
>
> Ahhh, bring unsere Anfänger auf keine falschen Ideen.
> Das funktioniert definitiv nicht! Die Abbruchbedingung ist immer false.
>
> Ich lass euch mal Knobeln...

Ach ja, die Integer promotion, hatte ich vergessen...

Autor: M. Köhler (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Und damit für mich EOD.

Für mich auch.

Frank M. schrieb:
> Lern erstmal C.

Das rate ich dir auch.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.