2015-04-22 11 views
9

Wenn ich den folgenden Code mit gcc kompilieren:-Wconversion Warnung während Operator << = auf unsigned char

conversion to ‘unsigned char’ from ‘int’ may alter its value [-Wconversion]

:

int main() 
{ 
    unsigned char c = 1; 
    c <<= 1; // WARNING ON THIS LINE 
    return 0; 
} 

ich diese Warnung Warum ? Was ist mit diesem Code falsch? Kann ich wirklich den Operator <<= auf einer unsigned char Variable verwenden?

Compilation Befehl:

g++ test.cpp -Wconversion -o test.exe

+1

Dies, so scheint mir, ist eine dieser "verdammten, wenn Sie tun und verdammt, wenn Sie nicht" Situationen, sowohl für Compiler-Schreiber und Benutzer. Als Benutzer ist das, was Sie geschrieben haben, sauber und produziert die beabsichtigte Antwort und ist im Allgemeinen völlig untadelig. Und es braucht kein zusätzliches linguistisches Durcheinander, um das Verständnis zu erschweren. Da es sich um einen Compiler-Writer handelt, gibt es technisch eine engere Konvertierung, daher ist die Warnung technisch korrekt. Aber ich kann nicht anders, als zu fühlen, dass in diesem Zusammenhang oder den analogen, die "kurz" betreffen (was vermutlich auch die Warnung auslöst), die Warnung wirklich nicht konstruktiv ist. –

Antwort

8

Dies ist eine gültige Warnung:

c <<= 1; 

entspricht:

c = c << 1 

und die Regeln für << sagen, dass die Operanden hochgestuft werden und in diesem Fall auf int hochgestuft werden und das Ergebnis vom Typ prorated ist. Es wird also am Ende eine Konvertierung von int zu unsigned char stattfinden, was zu einem geänderten Wert führen kann.

Der Code ist gültig, die Warnung informiert Sie darüber, dass eine implizite Konvertierung stattfindet und in einigen Fällen könnte die Konvertierung den Wert ändern. Wenn Sie einen Cast verwenden, wird die Warnung stummgeschaltet. Ergebnisse von impliziten Konvertierungen können sehr kontraintuitiv und in einigen Fällen nicht definiert sein. Siehe gcc Wconversion wiki for some details.

Ich sehe einen Weg, nicht ohne den Ausbau die Operation aus der Warnung manuell zu entfernen und mit static_cast:

c = static_cast<unsigned char>(c << 1); 

Wie wir aus dem langen Faden auf diesen gcc bug report nicht jeder fühlt, dass dies ein sehen ist nützlicher Fall für diese Warnung.

als Referenz aus den draft C++ standard Abschnitt 5.8 Shift-Operatoren:

Die Operanden von integralem oder unscoped Aufzählungstyp sein sollen und Integral Aktionen durchgeführt werden. Der Typ des Ergebnisses ist, dass der linke Operand gefördert [...]

und aus dem Abschnitt 5.17 Zuordnung und Verbindung Zuweisungsoperatoren:

Das Verhalten eines Ausdrucks der Form E1 op = E2 entspricht E1 = E1 op E2, außer dass E1 nur einmal ausgewertet wird. [...]

+1

Ich habe auch das Problem, wenn ein do 'c << = static_cast (1);'. Sagen Sie dann, dass es in C++ keinen Verschiebungsoperator für 1 Byte-Typen gibt? : -/ – Caduchon

+4

Siehe [Warum muss eine Abkürzung vor arithmetischen Operationen in C und C++ in ein int konvertiert werden?] (Http://stackoverflow.com/q/24371868/1708801), um zu begründen, warum Operanden zu breiteren Typen befördert werden . Hauptsächlich, weil es zu schnellerem Code führt. –

Verwandte Themen