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


von Samuel (Gast)


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



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

von Sven P. (Gast)


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.

von (prx) A. K. (prx)


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.

von Peter (Gast)


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?

von Karl H. (kbuchegg)


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.

von Praxisstudent (Gast)


Lesenswert?

Ich habe gerade das gleiche Problem. leider habe ich meinen Code aus 
diesem Artikel:

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

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

von Peter II (Gast)


Lesenswert?

Praxisstudent schrieb:
> und es kommt auch der oben beschriebene Fehler

in welcher Zeile kommt denn der Fehler?

von Praxisstudent (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

Praxisstudent schrieb:
> In der for-Schleife. kann

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

von UV (Gast)


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

von Praxisstudent (Gast)


Angehängte Dateien:

Lesenswert?

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

von Peter II (Gast)


Lesenswert?

Praxisstudent schrieb:
> und beim warning steht dann:

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

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

von Herbert (Gast)


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).

von Praxisstudent (Gast)


Lesenswert?

Ich geh mich mal schnell vergraben. Danke.

von W.A. (Gast)


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.

von Herbert (Gast)


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.

von M. K. (sylaina)


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:
1
uint8_t i;
2
...
3
for( i = 9; i != 0; i--){
4
  //do anything
5
}
6
...

: Bearbeitet durch User
von moeb (Gast)


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.

von Frank M. (ukw) (Moderator) Benutzerseite


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:
1
int8_t i;
2
3
for( i = 9; i >= 0; i--){
4
    //do anything
5
}

: Bearbeitet durch Moderator
von M. K. (sylaina)


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:
1
int8_t i;
2
3
for( i = 10; i != 0; --i){
4
    //do anything
5
}
;)

von Peter II (Gast)


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?
1
int i;
2
if ( i = GetValue() ) {
3
}

ist zulässig und auch sinnvoll

von Daniel A. (daniel-a)


Lesenswert?

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

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


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 ;-)

von moeb (Gast)


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!

von M. K. (sylaina)


Lesenswert?

Peter II schrieb:
> ...
>
> Warum sollte eine Zuweisung nicht erlaubt sein?
>
>
1
> int i;
2
> if ( i = GetValue() ) {
3
> }
4
>
>
> 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:
1
uint8_t i;
2
...
3
for( i = 9; i != 0; i--){
4
  //do anything
5
}
6
//do same as for-loop with i=0
7
...

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

: Bearbeitet durch User
von Klaus H. (klummel69)


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...

von moeb (Gast)


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.

von Student (Gast)


Lesenswert?

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

Es ging ja um Konstanten.
Ich habe zwar gerade keinen Compiler an, aber:
1
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:
1
if ("".equals(str)) {}

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

von Frank M. (ukw) (Moderator) Benutzerseite


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:
1
  while ((c = getchar ()) != EOF)
2
  {
3
      putchar ();
4
  }

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
1
    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.

von moeb (Gast)


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 ;)

von M. K. (sylaina)


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:
1
 c != EOF

zuvor wird die Anweisung
1
 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. ;)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

M. K. schrieb:
> Das ist keine Zuweisung in der Bedingung.

Doch.

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

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

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

: Bearbeitet durch Moderator
von Daniel A. (daniel-a)


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...

von M. K. (sylaina)


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.

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
Noch kein Account? Hier anmelden.