2010-06-05 10 views
13

ich die Entscheidung nur getroffen hatte, so viele Variablen aus unsigned zu int und auf neu zu kompilieren Sie den Code in Frage zu ändern, von dieser Warnmeldung begrüßt wurde:Was ist die Erklärung für „Warnung: unter der Annahme, dass die Schleife nicht unendlich ist“

freespace_state.c:203: warning: assuming that the loop is not infinite 

Die Linie in Frage:

for (x = startx; x <= endx; ++x, ++xptr) 

Diese Schleife ist 60 Zeilen Code (inc Leerraum/Klammern usw.), und hat eine goto darin, und mindestens ein Vorkommen von continue.

In diesem Fall denke ich, ich bin dankbar, dass GCC davon ausgeht, dass diese Schleife nicht unendlich ist, denn sie sollte niemals endlos durchlaufen.

Was versucht der GCC mir hier zu sagen?

Die Grammatik der Warnung weist fast darauf hin, dass die Warnung im Kontext einer anderen Warnung erfolgen sollte, aber in diesem Kontext gibt es keine.

[bearbeiten] Es ist alles vollständig meine eigene Schuld. Ich habe ein paar Optimierungs- und Warnoptionen aus einer Frage hier irgendwo gestohlen, ohne sie wirklich zu verstehen, und habe sie seitdem vergessen.

Siehe Mark Rushakoffs Antwort, und zusätzlich habe ich auch -Wunsafe-loop-optimizations verwendet, um ausdrücklich zu warnen, wenn GCC Annahmen über eine Schleife macht. Siehe http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

+0

Was für eine seltsame Nachricht ... Ich habe versucht zu verstehen, ob es mit dem Blogbeitrag unter http://blog.regehr.org/archives/140 zusammenhängt, aber es wäre seltsam, eine Benutzer-sichtbare Warnung zu senden . Dieser Blogbeitrag befasst sich mit stillen (und begründbaren) Optimierungen. –

+0

Sind Sie sicher, dass Sie in dieser Schleife nicht "int" und "unsigned" mischen? Sind all diese Variablen jetzt int? – AnT

+0

@AndreyT: Alle sind Ints außer Xptr, die ein Zeiger auf ein Uint64_t ist. –

Antwort

13

Laut this GCC patch from 2005 scheint GCC eine "unsichere Schleifenoptimierung" auszuführen (und Sie werden gewarnt, weil -funsafe-loop-optimizations eingestellt ist). Wenn die Schleife unendlich ist, wird diese bestimmte Optimierung irgendwie fehlschlagen.

Da Sie gesagt haben, dass es eine abschließende Schleife ist, klingt es so, als ob Sie nichts zu befürchten hätten.

Ein weiterer wichtiger Teil des Pflasters:

 
@opindex Wunsafe-loop-optimizations 
Warn if the loop cannot be optimized because the compiler could not 
assume anything on the bounds of the loop indices. With 
@option{-funsafe-loop-optimizations} warn if the compiler made 
+such assumptions. 
+0

Das scheint mir einen Sinn zu ergeben. –

0

Ich denke, dass GCC Ihnen sagt, dass es nicht feststellen kann, dass die Schleife nicht unendlich ist und unabhängig von der Kompilierung weitergeht. Es ist eine Warnung, kein Fehler, etwas, über das Sie nachdenken sollten.

+2

Ein Laufzeitfehler wird niemals von einem Kompilierzeitfehler verursacht, sondern kann ein Ergebnis nicht beachteter Warnungen sein. –

0

Der GCC Grund warnt Sie ist, weil es von einer unsicheren Optimierung gezogen haben. Statt

for (x = startx; x <= endx; ++x, ++xptr) 

es im Grunde verwendet:

for(x = startx; x < (endx+1); ++x, ++xptr) 

, die nur richtig, wenn endx+1 nicht überläuft, aber dies geschieht, wenn endx der größtmögliche Wert ist, was bedeutet, dass x <= endx immer wahr ist. Der Compiler geht davon aus, dass dies nicht geschieht.

Die Warnung ist manchmal etwas verwirrend, weil es nicht die Endlichkeit der Schleife ist, die hier der Punkt ist. Ich weiß nicht, ob es einen besseren Kandidaten für eine Nachricht gibt, die kurz genug für eine Compiler-Warnung wäre.

Ein Beispiel ist der Fall, in dem zum Beispiel x und endx ganzen Zahlen sind die Optimierung tatsächlich als erlaubt durch die Norm interpretiert werden könnte, wenn endx==MAX_INT Sie die Bedingung wahr haben würden, die schließlich zu diesen x führen werden überläuft, die nicht definiert ist Verhalten bedeutet dies, dass der Compiler davon ausgehen kann, dass dies nicht geschieht. Um die Schleife vollständig zu überspringen, ist ein standardkonformes Verhalten gemäß diesen Interpretationen. Ein anderer Fall ist, wenn das Programm nicht während der Schleife endet oder den flüchtigen Speicher ändert (dh beobachtbares Verhalten hat), was bedeutet, dass eine Endlosschleife ein undefiniertes Verhalten bedeutet (IIRC, zumindest der Compiler darf davon ausgehen, dass dies nicht der Fall ist) nicht passieren).