Konvertierung zu std :: arrayunsigned char, 1ul :: value_type von int kann seinen Wert ändern

8

Der Parameter -Wconversion GCC erzeugt beim Kompilieren dieses Programms die Warnung aus dem Titel:

%Vor%

So kompiliere ich es: g++- -Wall -Wextra -Wconversion -pedantic -std=c++0x test.cpp und ich benutze GCC 4.5.

Mache ich hier etwas Illegales? Kann es in bestimmten Szenarien zu Problemen führen? Warum würde die | eine int erzeugen?

    
Mihai Todor 20.08.2012, 14:22
quelle

3 Antworten

6
  

Mache ich hier etwas Illegales?

Sie konvertieren von einem signierten Typ in einen unsignierten Typ. Wenn der vorzeichenbehaftete Wert negativ wäre, wäre das vorzeichenlose Ergebnis ein implmentationsdefinierter nicht-negativer Wert (und daher nicht derselbe wie der Anfangswert).

  

Kann es in bestimmten Szenarien zu Problemen führen?

Nur wenn der Wert negativ sein kann. Das könnte der Fall bei etwas exotischen Architekturen sein, bei denen sizeof (char) == sizeof (int) ist, oder wenn dein Code etwas komplizierteres getan hat als das Kombinieren zweier Werte mit | .

  

Warum würde die | eine int erzeugen?

Weil alle Integer-Werte hochgestuft werden , bevor sie in arithmetischen Operationen verwendet werden. Wenn ihr Typ kleiner als int ist, werden sie zu int hochgestuft. (Es gibt etwas mehr als Werbung, aber das ist die Regel, die für diese Frage relevant ist).

    
Mike Seymour 20.08.2012, 14:29
quelle
2

Ja, eine Zeichenkette besteht aus char, das signiert ist, Sie haben ein Array von unsigned char.

wie | ein int wird produziert, es heißt integer promotion. im Grunde macht der Compiler beide ints, macht ein |, macht sie dann wieder char.

Es läuft jedoch auf ein Problem. Nach den C / C ++ - Standards erfolgt eine Integer-Promotion, wenn der Typ, für den der Promoter ist, alle Werte des Typs enthalten kann, von dem der Promoter ist. so fördert es das unsigned char zu einem unsigned int und das signierte char zu einem signed int. Förderung eines signierten Wertschildes - erweitert es. Also sagen Sie, Sie haben -1 oder 0xFF oder 11111111. Das ist erweitert auf 1000000000000000000000000001111111 signed int ((int) -1). Offensichtlich wird das ein anderes Ergebnis haben als | 'ing mit 11111111 ((char) -1) intuitiv erwarten würde.

Sehen Sie hier für weitere Informationen: hier erklärt es eine Art 'Workaround'

    
std''OrgnlDave 20.08.2012 14:24
quelle
2

Ergebnis von unsigned char | char ist int pro Integer-Konvertierungsregeln . Wenn Sie int zurück zu unsigned char zuweisen, kann die Zuweisung den Wert für int abschneiden - der Compiler weiß nicht, wie groß der Wert in int ist.

Um den Compiler zum Schweigen zu bringen:

byteArray[0] = static_cast<unsigned char>(byteArray[0] | test[0]);

    
Leonid Volnitsky 20.08.2012 14:30
quelle