Frage

Ich baue mein Projekt mit -Wconversion Warnflag des GCC. (Gcc (Debian 4.3.2-1.1) 4.3.2) auf einem 64-Bit-GNU / Linux OS / Hardware. Ich bin es nützlich bei der Identifizierung zu finden, wo ich Arten oder verloren Klarheit gemischt habe darüber, welche Arten verwendet werden sollen.

Es ist nicht so hilfreich in den meisten anderen Situationen, in denen es Warnungen aktivieren und ich frage wie kann ich mit diesen beschäftigen bedeuten:

enum { A = 45, B, C };   /* fine */

char a = A;              /* huh? seems to not warn about A being int. */
char b = a + 1;          /* warning converting from int to char */
char c = B - 2;          /* huh? ignores this *blatant* int too.*/
char d = (a > b ? b : c) /* warning converting from int to char */

Aufgrund der unerwarteten Ergebnisse der obigen Tests (Fälle a und c) Ich bin auch für diese Unterschiede zu fragen auch erklärt werden.

Edit:? Und ist es über Engineering all diese mit (char) zu werfen um die Warnung zu verhindern

Edit2: Einige zusätzliche Fälle (im Anschluss an obigen Fällen):

a += A;         /* warning converting from int to char */
a++;            /* ok */
a += (char)1;   /* warning converting from int to char */

Abgesehen davon, was ich frage ist subjektiv, und ich möchte hören, wie andere Leute mit den Konvertierungswarnungen in Fällen wie diesen beschäftigen, wenn man bedenkt, dass einige Entwickler befürworten Entfernen alle Warnungen .

YAE:

Eine mögliche Lösung ist, einfach rechts ints statt chars zu benutzen? Naja, eigentlich, nicht nur, dass es mehr Speicher benötigt, ist es langsamer ist auch, wie man durch den folgenden Code demonstriert. Die Mathematik Ausdrücke sind einfach da, die Warnungen zu erhalten, wenn sie mit -Wconversion gebaut. Ich nahm die Version char Variablen laufen würde langsamer als die Verwendung von ints aufgrund der Umbauten, aber auf meinem (64-Bit-Dual-Core-II) System der int Version ist langsamer.

#include <stdio.h>

#ifdef USE_INT
typedef int var;
#else
typedef char var;
#endif

int main()
{
    var start = 10;
    var end = 100;
    var n = 5;
    int b = 100000000;
    while (b > 0) {
        n = (start - 5) + (n - (n % 3 ? 1 : 3));
        if (n >= end) {
            n -= (end + 7);
            n += start + 2;
        }
        b--;
    }
    return 0;
}

Pass -DUSE_INT auf gcc die int Version des obigen Schnipsel zu bauen.

War es hilfreich?

Lösung

Wenn Sie /* int */ sagen meinst du es eine Warnung über das ist zu geben? Ich sehe keine Warnungen an alle in diesem Code mit gcc 4.0.1 oder 4.2.1 mit -Wconversion. Der Compiler wandelt diese Aufzählungen in Konstanten. Da alles zum Zeitpunkt der Kompilierung bekannt ist, gibt es keinen Grund, eine Warnung zu erzeugen. Der Compiler kann die ganze Unsicherheit optimieren heraus (die folgende ist Intel mit 4.2.1):

    movb    $45, -1(%rbp)    # a = 45
    movzbl  -1(%rbp), %eax
    incl    %eax
    movb    %al, -2(%rbp)    # b = 45 + 1
    movb    $44, -3(%rbp)    # c = 44 (the math is done at compile time)
    movzbl  -1(%rbp), %eax   
    cmpb    -2(%rbp), %al
    jle     L2               
    movzbl  -2(%rbp), %eax
    movb    %al, -17(%rbp)
    jmp     L4
L2: 
    movzbl  -3(%rbp), %eax
    movb    %al, -17(%rbp)
L4:
    movzbl  -17(%rbp), %eax
    movb    %al, -4(%rbp)    # d = (a > b ? b : c)

Dies ist auf Optimierungen ohne sich umzudrehen. Mit Optimierungen, wird es b und d für Sie bei der Kompilierung berechnen und ihre endgültigen Werte codieren (wenn es sie tatsächlich für etwas braucht). Der Punkt ist, dass gcc bereits ausgearbeitet, dass es hier kein Problem sein, weil alle möglichen Werte in einem char passen.

EDIT: Lassen Sie mich das etwas ändern. Es ist ein möglicher Fehler bei der Zuordnung von b, und der Compiler wird es nie fangen, auch wenn es sicher ist. Zum Beispiel, wenn b=a+250;, dann wird dies sicher sein b überzulaufen, aber gcc eine Warnung nicht erteilen. Es ist, weil die Zuordnung a legal ist, a ein char ist, und es ist Ihr Problem (nicht der Compiler), um sicherzustellen, dass Mathematik nicht überläuft zur Laufzeit.

Andere Tipps

Vielleicht kann der Compiler bereits sehen, dass alle Werte in eine char passen, so dass es Warnung nicht stört. Ich würde die enum erwarte gleich zu Beginn der Zusammenstellung gelöst werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top