Forum: Compiler & IDEs suggest parentheses around assignment used as truth value


von chris (Gast)


Lesenswert?

Hallo,

ich bekomme bei folgender if-Schleife, folgende Warnung:

if(Array_counter==64 && Tmp==255)
{
for(uint8_t i=3;i=64;i++)
Array_counter=0;
}

warning: suggest parentheses around assignment used as truth value

denke, aber das die if Anweisung richtig ist. hat damit jemand schon
Erfahrungen?

danke

cu chris

von chris (Gast)


Lesenswert?

es sollte natürlich:

if(Array_counter==64 && Tmp==255)
{
for(uint8_t i=3;i=64;i++)
Tmp[i]=0;
}

heißen...

von Rolf Magnus (Gast)


Lesenswert?

> ich bekomme bei folgender if-Schleife, folgende Warnung:

Du meinst "for-Schleife". if ist nur eine Verzweigung, keine
Schleife.

Die Warnung gibt der Compiler aus, weil er an einer Stelle, an der ein
boole'scher Wert erwartet wird, eine Zuweisung gefunden hat. Das ist
oft eine Fehlerquelle

> for(uint8_t i=3;i=64;i++)

Diese Schleife l��uft solange ab, wie 64 ungleich 0 ist.
Vor jedem Durchlauf wird i auf den Wert 64 gesetzt. Der zweite Ausdruck
beim for sollte eher die Bedingung sein, unter der die Schleife nochmal
weiterl��uft. Welche das ist, wei�� iist
aus dem Code schwer zu erkennen. Vermutlich != oder <.

von Rolf Magnus (Gast)


Lesenswert?

Hmm, hab da grad noch was gesehen:

> if(Array_counter==64 && Tmp==255)

Hier scheint Tmp ein Integer zu sein.

> Tmp[i]=0;

Hier benutzt du auf einmal den Index-Operator, als sei es ein Array
oder Zeiger.

von chris (Gast)


Lesenswert?

Hallo Rolf,

folgendes will ich machen...

"if" Bedingung -> Wenn Array_counter den Wert 64 hat, UND Tmp (ist
ein array Tmp[Array_counter]) den Wert 255 hat, soll die "for"
schleife ausgelößt werden.

Diese "for" Schleife soll den Wert von Tmp von array nummer 3 bis 64
wieder =0 setzen.

oha: es sollte klappen, wenn ich statt i=64 ... i==64 schreiben
würde.... was schlecht.....

cu

von Rolf Magnus (Gast)


Lesenswert?

> ...UND Tmp (ist ein array Tmp[Array_counter]) den Wert 255 hat...

Das geht nicht. Wie soll das gesamte Array den Wert 255 haben? Ein
Array hat mehrere Elemente. Du musst dich schon fuer ein Element
entscheiden, dessen Wert 255 sein soll.

> oha: es sollte klappen, wenn ich statt i=64 ... i==64 schreiben
> würde.... was schlecht.....

Du solltest mein vorheriges Posting nochmal durchlesen. Die Schleife
wird solange durchgefuehrt, wie die Bedingung WAHR ist, also in diesem
Fall, solange i den Wert 64 hat. Diesen Wert erreicht es aber nie. Es
wird vor dem ersten Durchlauf mit 3 initialisiert, was ungleich 64
wird, also wird die Schleife gar nicht ausgefuehrt. Wie ich schon
schrieb, brauchst du vermutlich eher < statt ==.

von johnny.m (Gast)


Lesenswert?

> warning: suggest parentheses around assignment used as truth value

Diese Warnung gibt Dir zunächst mal nur den Hinweis, etwas großzügiger
mit Klammern (engl. parentheses) umzugehen und bezieht sich
(höchst)wahrscheinlich auf 'if(Array_counter==64 && Tmp==255)'. Ich
habe die Prioritäten der Operatoren jetzt nicht im Kopf, aber die
Warnung müsste eigentlich verschwinden, wenn Du schreibst
'if((Array_counter==64) && (Tmp==255))'.
Ansonsten könnte es passieren (da in meiner Erinnerung '&&' eine
höhere Priorität hat als '=='), dass der Ausdruck falsch ausgewertet
wird. Der Compiler hat das Problem aber anscheinend erkannt und weist
Dich (freundlich) darauf hin, dass Du Deine Schreibweise etwas
präzisieren solltest, für den Fall, dass Du mal an einen Compiler
gerätst, der das nicht merkt und einfach stur drauflos kompiliert...

von johnny.m (Gast)


Lesenswert?

...Ach ja, das was Rolf geschrieben hat, ist natürlich auch zu beachten,
auch wenn es sicher nicht das ist, was zu der Warnung geführt hat...

von Rolf Magnus (Gast)


Lesenswert?

Die Ursache der Warnung war mit Sicherheit das "i=64" im if, denn da
wird ein "assignment" als "truth value" benutzt. An der von dir
erwaehnten Stelle kommt gar keine Zuweisung vor.

von Peter D. (peda)


Lesenswert?

Die Ursache der Warnung war mit Sicherheit das "i=64" im if


Das stimmt.

Die Zuweisung i=64; ist ungleich 0 und daher immer wahr, d.h. es ergibt
sich eine Endlosschleife.

In C hat jeder Zuweisungsausdruck implizit auch einen Wert, daher geht
auch folgendes: a = b = c;


Peter

von Peter D. (peda)


Lesenswert?

@johnny

"(da in meiner Erinnerung '&&' eine höhere Priorität hat als
'==')"

Da trügt Dich die Errinnerung, die logischen Operatoren sind im Rang
tiefer, was ja oft sinnvoll ist.


Peter

von A.K. (Gast)


Lesenswert?

"Ansonsten könnte es passieren (da in meiner Erinnerung '&&' eine
höhere Priorität hat als '=='), dass der Ausdruck falsch ausgewertet
wird."

Die klassische Falle liegt bei &,| nicht bei &&,||. Also typischem
Controller-Zeug wie
  if (a & 0x20 == 0)
und
  if ((a & 0x20) == 0)

von Peter D. (peda)


Lesenswert?

"Die klassische Falle liegt bei &,|"


Genau.
Da haben sich die C-Erfinder nicht mit Ruhm bekleckert.


Peter

von johnny.m (Gast)


Lesenswert?

> ...kommt gar keine Zuweisung vor...

Hm, stimmt natürlich (Diesmal war ich anscheinend nicht ganz
wach...Das war aber auch ne Hitze gestern...)

> Die klassische Falle liegt bei &,| nicht bei &&,||. Also
> typischem Controller-Zeug wie
>   if (a & 0x20 == 0)
> und
>   if ((a & 0x20) == 0)

Richtig, und deshalb sollte man lieber immer ein paar Klammern mehr
spendieren als ein paar zu wenig... Dann ist man immer auf der sicheren
Seite und es ist übersichtlicher...

von Oliver (Gast)


Lesenswert?

"Diese "for" Schleife soll den Wert von Tmp von array nummer 3 bis
64
wieder =0 setzen."

"oha: es sollte klappen, wenn ich statt i=64 ... i==64 schreiben
würde.... was schlecht....."

Dann sollte es ohne Warnung kompilieren, aber wenn du i<=64 schreibst,
tut es auch noch, was du willst.

Oliver

von chris (Gast)


Lesenswert?

Hallo Leute,
aus einem sehr einfachen Schreib/Denkfehler von mir ist doch ein sehr
ansehnlicher Thread geworden.

a) die Fehlermeldung kommt durch das i=64, bzw. i==64.
   Auch sollte ich sagen, das die funktion nicht gemacht hat was ich

   wollte, denn das "<" war die richtige Bedingung.

b) array. auch da habe ich mich vertan, denn wenn ich z.b. einen
pointer
   auf ein array setze denn mache ich das ohne die "[]" Klammern.

Wie auch immer, die warning ist weg und ich habe wieder viel
gelernt...

dank an euch

cu

chris

von ich (Gast)


Lesenswert?

Hi Leute, zwar schon etwas älter der Beitrag, aber ich habe im Moment 
ein recht ähnliches Problem. Ich bastle gerade mit string Funktionen 
herum und versuche ein strcat zu basteln.
Mein eigenes funktioniert, aber ist sehr aufwendig. Nun habe ich ein 
bisschen im Netz gesucht und folgendes gefunden:
1
char *strcat(char *dst, const char *src) {
2
  char *cp = dst;
3
  while (*cp) cp++;
4
  while (*cp++ = *src++);
5
  return dst;
6
}
Nun kommt diese Meldung:
1
strcat.c:7: error: suggest parentheses around assignment used as truth value
7 ist die zweite while-Schleife, while(*cp++ = *src++);
Allerdings bekomm ich nicht genau raus, warum diese Zeile nicht 
funktioniert. Kann mir da einer von euch helfen?

Das Obige stammt von hier 
http://www.jbox.dk/sanos/source/lib/string.c.html

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

ich wrote:
> Hi Leute, zwar schon etwas älter der Beitrag,...

Ja, und daher macht man für ein neues Problem höflicher Weise einen
neuen Thread auf.


> Nun kommt diese Meldung:
>
1
strcat.c:7: error: suggest parentheses around assignment used as
2
> truth value
3
>

Error?  Das sollte eine Warnung sein.

> 7 ist die zweite while-Schleife, while(*cp++ = *src++);
> Allerdings bekomm ich nicht genau raus, warum diese Zeile nicht
> funktioniert.

Sie funktioniert, sie ist nur schlechter Stil.

Schöner wäre
1
while ((*cp++ = *src++) != 0);

denn das macht die Abbruchbedingung offensichtlich.

Die Warnung wird man auch schon mit der angeratenen Klammer allein
los:
1
while ((*cp++ = *src++));

denn damit drückt man dem Compiler aus: ,,Ich habe drüber nachgedacht,
was das bedeutet, das ist OK so.''

von ich (Gast)


Lesenswert?

> Ja, und daher macht man für ein neues Problem höflicher Weise einen
> neuen Thread auf.
Hmm, eigentlich dachte ich gerade andersherum ;)

> Error?  Das sollte eine Warnung sein.
gcc -Werror, damit wird jede Warnung als Fehler genommen.

Danke für die Hilfe, es compiliert nun ohne Probleme :)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

ich wrote:

>> Error?  Das sollte eine Warnung sein.
> gcc -Werror, damit wird jede Warnung als Fehler genommen.

Das steht dann trotzdem nicht so da, wie du das oben zitiert hast,
sondern stattdessen steht:
1
cc1: warnings being treated as errors
2
foo.c:1: warning: ...

Es wird hier nicht gern gesehen, wenn du die Fehlermeldungen und
Warnungen abtippst, statt sie mit copy&paste zu übernehmen, da sich
nicht selten dann ins Abgetippte andere Fehler einschleichen.

von ich (Gast)


Lesenswert?

Die ist nicht abgetippt (gewesen), war c&p. Ich habe nur das "treated as 
errors..." rausgelassen, weil ich dachte, dass das klar wäre, wenn da 
Error steht.
Hier nochmal, diesmal komplett:
1
   [CC] strcat.o
2
cc1: warnings being treated as errors
3
src/string/strcat.c: In function 'strcat':
4
src/string/strcat.c:7: error: suggest parentheses around assignment used as truth value

Deine Meldung sieht aber ein wenig anders aus...
Mein Compiler ist gcc-4.3.3 als i386-elf cross-compiler eingerichtet mit 
den binutils 2.16, ebenfalls i386-elf....

von Jörg G. (joergderxte)


Lesenswert?

Warum nimmst du für dein Programm nicht die string.h (die gehört doch 
AFAIK zum C-Standard)?
1
char *strcat(char *dst, const char *src) {
2
  char *cp = dst;
3
  while (*cp)       // << was soll diese Schleife?
4
     cp++;          // Ab hier zeigt cp auf das letzte Zeichen
5
                    // von dst  (==0)
6
  while((*cp++ = *src++)) // hier sollst du extra Klammern
7
    ;                     // (wie bereits erwaehnt)
8
  return dst;
9
}
Und das 'richtige' strcat() kann auch mit überlappenden strings umgehen.

hth, Jörg

von Karl H. (kbuchegg)


Lesenswert?

Jörg G. wrote:
> Warum nimmst du für dein Programm nicht die string.h (die gehört doch
> AFAIK zum C-Standard)?

Gute Frage


> Und das 'richtige' strcat() kann auch mit überlappenden strings umgehen.

Seit wann?

von ich (Gast)


Lesenswert?

> Warum nimmst du für dein Programm nicht die string.h (die gehört doch
> AFAIK zum C-Standard)?
string.h gehört in die C-Lib, was aber meines Wissens entweder standard 
oder "nahezu-standard" ist.
Ich nehme die nicht, weil ich die nicht verfügbar habe. Ich programmiere 
für einen Rechner ohne Betriebssystem.

von Karl H. (kbuchegg)


Lesenswert?

ich wrote:
>> Warum nimmst du für dein Programm nicht die string.h (die gehört doch
>> AFAIK zum C-Standard)?
> string.h gehört in die C-Lib, was aber meines Wissens entweder standard
> oder "nahezu-standard" ist.

Ist Standard.

> Ich nehme die nicht, weil ich die nicht verfügbar habe. Ich programmiere
> für einen Rechner ohne Betriebssystem.

? Ob du ein Betriebssystem zur Verfügung hast oder nicht, ist für die 
meisten der Funktionen in der Standard-Library unerheblich. Gerade die 
String-Funktionen sind ja (bis auf strdup) völlig unabhängig von einem 
Betriebssystem.
Aber ok, wenn du sie nicht hast, dann hast du sie nicht.
1
size_t strlen( const char* str )
2
{
3
  size_t len = 0;
4
5
  while( *str++ )
6
    len++;
7
8
  return len;
9
}
10
11
char* strcpy( char* dst, const char* src )
12
{
13
  char* tmp = dst;
14
  while( (*dst++ = *src++) )
15
    ;
16
17
  return tmp;
18
}

die meisten der anderen String-Funktionen aus der str... Familie sind 
ähnlich einfach gestrickt.

von Jörg G. (joergderxte)


Lesenswert?

>> Und das 'richtige' strcat() kann auch mit überlappenden strings umgehen.
>Seit wann?
Das kann strcat() nicht, da hast du natürlich recht (Ich hab nicht 
nachgeschaut/-gedacht: src ist ja "const char*" - zumindest bei der 
avr-libc).

>Ich programmiere für einen Rechner ohne Betriebssystem.
Das tun die anderen (z.B. für den AVR) auch, mit libc...

hth, Jörg

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

ich wrote:

> Deine Meldung sieht aber ein wenig anders aus...
> Mein Compiler ist gcc-4.3.3

Ja, ich sehe gerade, dass sich das mit GCC 4.3 in der Tat geändert
hat.  Sorry für die flachse Anschuldigung dann.

von ich (Gast)


Lesenswert?

1
die meisten der anderen String-Funktionen aus der str... Familie sind
2
ähnlich einfach gestrickt.
Das habe ich auch schon gemerkt, ich gucke vorher immer noch in 
verschiedene offen c-Libs und Foren durch, wie z.b. osdev.org und die 
http://pdclib.sourceforge.net/ .

Die glibc ist mir zu aufgebläht, da ist es nicht gerade einfach um zu 
sehen, WIE die verschiedenen Funktionen gestrickt sind. Ausserdem müsste 
man sie doch wohl erst noch auf "nichts" portieren, da ich ja komplett 
von 0 anfange. Ich müsste erstmal, wie z.B. hier beschrieben 
http://wiki.osdev.org/OS_Specific_Toolchain einiges drumherum 
programmieren um die glibc zu portieren (was dann auch wieder einiges zu 
tun sein wird...).

Im Moment komme ich mit meinen eigenen Funktionen auf eine ca 15kb 
grosse binary inkl. UART, 80*25 Text in 16 Farben, Tastatur, Timer, 
Beeper. Das kann aber 100%ig noch durch geschicktere Programmierung 
gedrückt werden. Da möchte ich sehen, dass man eine glibc so weit 
zusammenquetscht um genau das zu machen, was ich jetzt mache. Genau 
deshalb und um mal zu sehen wie sowas gemacht wird, habe ich mich für 
x86 und selber Programmieren entschieden.

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.