2013-10-18 19 views
9

Widziałem kawałek poprawnego kodu C, który próbowałem skompilować jako C++ i dostałem błąd, którego nie mogę zrozumieć.Konwersja z char * do podpisanego char *

char* t; 
signed char* v = t; 

error: invalid conversion from char* to signed char*

Z tego co dowiedziałem się, char i signed char są semantycznie identyczne, ale są nadal uważane za odmienne przez kompilator.

Wiem, że błąd wynika z różnicy między tymi dwoma typami, moje pytanie brzmi: Dlaczego ta różnica istnieje?

O ile wiem char jest realizowany albo jako signed char lub jako unsigned char więc powinien być identyczny z jednej lub drugiej strony.


Konsultowałem się z this question i nie odpowiada na pytanie, które chcę poznać.

+1

Lubię myśleć o '' signed' i niepodpisane char' jak arytmetycznych * * typów, tylko małych liczb całkowitych, w istocie, podczas gdy 'char' jest I/Typ O - argumenty wiersza poleceń, środowisko i odczyt/zapis poprzez pliki są wykonywane pod kątem znaków. –

+1

to pytanie zostało już odebrane na http://stackoverflow.com/questions/436513/char-signed-char-char-unsigned -char - najbardziej podstawowe wyjaśnienie jest takie, że 'unsigned char' zawiera się w przedziale od 0..255 i "signed char" ma zakres od -127..128. Więc nie możesz przekonwertować 'signed char' z -42 na' unsigned char' lub skonwertować 'unsigned char' z 142 na' signed char'. 'char' jest zwykle czytane jako' signed char'. –

+0

@alle_meije i 'signed char' i' char' * są * równe. I nie widziałem tego pytania, chociaż szukałem go ... – Geoffroy

Odpowiedz

9

Właściwie to w końcu okazało się, że część Spec rozmowy na ten temat:

3.9.1 Fundamental types

  1. Objects declared as characters (char) shall be large enough to store any member of the implementation’s basic character set. If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character. It is implementation-defined whether a char object can hold negative values. Characters can be explicitly declared unsigned or signed. Plain char, signed char, and unsigned char are three distinct types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements (3.11); that is, they have the same object representation. For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.
-1

powiem, co wiem ...

Dla typu char C++ ma rozmiar 1 '' bajt ..

jeśli jest podpisany char, to zakres wynosi od -128 do 127 w przeciwnym razie, jeśli jest bez znaku zakres znaków wynosi od 0 do 256

wszyscy znamy 8 bitów w bajtach w przypadku znakowany znak MSB (tj. lewy najbardziej bitowy) zostanie użyty dla znaku reszta 7 bitów dla wartości tworzących zakres 0-2^7 (0-127). Znak ujemny (logiczny 1) i (logiczny 0) dla pozytywny znak na MSB. np. (1 0000111 = -7,0 0000111 = + 7) i 1 0000000-128. Jednak jeśli przypiszesz 129 dla podpisanej wartości char, to zostanie ona automatycznie zmieniona na -127 (tj. Wartość w zakresie (-128,127)

w drugim przypadku typu bez znaku wszystkie 8 bitów jest używane dla wartości tj. Zakres jest 0-2^8 (0-255), tutaj 0-127 jest takie samo jak znakowany znak i te należące do -128 do 0 można znaleźć w zakresie 128-255 w niepodpisanym zestawie znaków

Tak możemy powiedzieć i miejscu pamięci wewnętrznej różnicy między tymi dwoma rodzajami „podpisane” i „bez znaku”, który może być problem.

+0

@Geoffroy mam nadzieję, że to pomoże! – Raon

+0

Dzięki za odpowiedź, to wszystko prawda, ale to nie był rzeczywisty problem :) – Geoffroy

+0

@Raon: Właściwie standard mówi: 'sizeof (char) == 1' ale nie ustala, że ​​1 => 1 Byte, ale po prostu że 'char' jest najmniejszym blokiem pamięci, który obsługuje twój system. Niektóre systemy ezoteryczne mogą używać "1KB" jako najmniejszego możliwego do przydzielenia rozmiaru ... Należy również pamiętać, że standard nie określa reprezentacji typów podpisanych! – MFH

0

From what I learned, char and signed char are semantically identical, but are still >considered as different by the compiler.

NO. char nie jest semantycznie identyczne do signed char.

W przeciwieństwie do innych typów całek (całkowitych, długich, krótkich itp.) Nie ma gwarancji, że znak bez nazwy signed lub unsigned będzie oznaczony jako signed. To jest definicja zdefiniowana. Niektóre architektury zdefiniować go jako signed, inni jak unsignedw realnym świecie

Więc z char, jeśli uzyskiwany znak jest ważne, to naprawdę trzeba określić, które chcesz.

Moja rekomendacja byłaby, jeśli robisz manipulowanie znakami itp. Lub używając wywołania api, które używa char lub char *, użyj char. Jeśli chcesz tylko 8-bitową wartość całkowitą, upewnij się, że podałeś signed char lub unsigned char, tak że za kilka lat, gdy przeniesiesz się do innej architektury, nie zostaniesz ugryziony w tyłek.

Albo jeszcze lepiej, użyj uint8_t lub int8_t dla 8-bitowych liczb całkowitych.

EDIT: Z własnej odpowiedzi:

These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.