Czy są maszyny, w których sizeof (char)! = 1 lub przynajmniej CHAR_BIT> 8?

93

Czy są maszyny (lub kompilatory), gdzie sizeof(char) != 1?

Czy norma C99 mówi, że sizeof(char)implementacja zgodności ze standardami MUSI wynosić dokładnie 1? Jeśli tak, podaj mi numer sekcji i cytat.

Aktualizacja: Jeśli mam komputer (procesor), który nie może adresować bajtów (minimalny odczyt to 4 bajty, wyrównane), ale tylko 4-s bajtów ( uint32_t), czy kompilator dla tej maszyny może zdefiniować sizeof(char)na 4? sizeof(char)będzie 1, ale znak będzie miał 32 bity ( CHAR_BITmakra)

Update2: Ale sizeof wynik NIE JEST BYTEM! to jest rozmiar CHAR. A znak może mieć 2 bajty lub (może być) 7 bitów?

Aktualizacja 3: Ok. Wszystkie maszyny mają sizeof(char) == 1. Ale jakie maszyny mają CHAR_BIT > 8?

osgx
źródło
4
Martwię się zgodnością ze standardem C99. Ściśle współpracuję z kompilatorami C99
osgx,
2
Ponieważ Unicode staje się jeszcze ważniejszy, mogą pojawić się niestandardowe kompilatory, które używają znaków Unicode jako char(zamiast wchar). Nawet jeśli standard mówi, że sizeof(char)musi to być 1, nie polegałbym na tym założeniu.
Chip Uni
14
nie ma kompilatorów C, w których sizeof (char) jest różna od 1, unicode lub nie.
nr
6
@Chip: sizeof(char)zawsze wynosi 1, nawet jeśli znak jest 32-bitowy (jak to ma miejsce w niektórych systemach). C ma mnóstwo fajnych brodawek.
Nick Bastin
2
Wszystkie wersje standardu C wymagają, aby wartość CHAR_BIT wynosiła co najmniej 8; nie możesz mieć CHAR_BIT == 7 i być zgodnym ze standardami. Jednak jest całkowicie wykonalne, aby maszyny miały CHAR_BIT> 8. Wydaje mi się, że stare maszyny Cray miały ( sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)na tych; nie pamiętam, sizeof(int) == sizeof(long)czy CHAR_BIT miał 32 czy 64; spodziewam się, że było to 32 i myślę sizeof(long) == 1też). (Możesz znaleźć odniesienie do podręcznika Cray C , ale nie dostęp do niego online ).
Jonathan Leffler

Odpowiedzi:

91

Jest to zawsze jeden w C99, sekcja 6.5.3.4:

Po zastosowaniu do operandu, który ma typ char, unsigned char lub signed char (lub jego kwalifikowaną wersję), wynikiem jest 1.

Edycja: nie jest częścią twojego pytania, ale do zainteresowania ze strony Harbison and Steele, wyd. (przed c99) str. 148:

Za jednostkę pamięci przyjmuje się ilość miejsca zajmowanego przez jedną postać; wielkość typu obiektu charwynosi zatem 1.

Edycja: W odpowiedzi na zaktualizowane pytanie istotne jest następujące pytanie i odpowiedź od Harbison and Steele (ibid, Ex. 4 w Rozdziale 6):

Czy dopuszczalna jest implementacja C, w której typ charmoże reprezentować wartości z przedziału od -2 147 483 648 do 2 147 483 647? Jeśli tak, co będzie w sizeof(char) ramach tego wdrożenia? Jakie byłyby najmniejsze i największe zakresy czcionek int?

Odpowiedź (ibid, s. 382):

Dozwolone jest (jeśli jest to marnotrawstwo), aby implementacja używała 32 bitów do reprezentowania typu char. Niezależnie od implementacji wartość sizeof(char)zawsze wynosi 1.

Chociaż nie dotyczy to konkretnie przypadku, w którym, powiedzmy, bajty mają 8 bitów i charsą 4 z tych bajtów (w rzeczywistości niemożliwe z definicją c99, patrz poniżej), fakt, że sizeof(char) = 1zawsze jest jasny ze standardu c99 oraz Harbison i Steele.

Edycja: W rzeczywistości (jest to odpowiedź na twoje pytanie Upd 2), jeśli chodzi o c99 sizeof(char) jest w bajtach, z sekcji 6.5.3.4 ponownie:

Operator sizeof zwraca rozmiar (w bajtach) swojego operandu

więc w połączeniu z powyższym cudzysłowem bajty 8-bitowe i char4 z tych bajtów są niemożliwe: dla c99 bajt to to samo, co a char.

W odpowiedzi na twoją wzmiankę o możliwości 7 bitów char: nie jest to możliwe w c99. Zgodnie z sekcją 5.2.4.2.1 normy minimum to 8:

Ich wartości zdefiniowane w ramach realizacji powinny być równe lub większe [podkreślenie moje] pod względem wielkości od pokazanych, z tym samym znakiem.

- liczba bitów dla najmniejszego obiektu, który nie jest polem bitowym (bajtem)

 **CHAR_BIT 8**

- minimalna wartość dla obiektu typu signed char

**SCHAR_MIN -127//−(27−1)** 

- maksymalna wartość dla obiektu typu signed char

**SCHAR_MAX +127//27−1** 

- maksymalna wartość dla obiektu typu unsigned char

**UCHAR_MAX 255//28−1** 

- minimalna wartość dla obiektu typu char

**CHAR_MIN**    see below 

- maksymalna wartość dla obiektu typu char

**CHAR_MAX**    see below

[…]

Jeżeli wartość obiektu typu char jest traktowana jako liczba całkowita ze znakiem, gdy jest używana w wyrażeniu, wartość CHAR_MIN powinna być taka sama jak wartość SCHAR_MIN, a wartość CHAR_MAX będzie taka sama jak wartość SCHAR_MAX. W przeciwnym razie wartość CHAR_MIN będzie wynosić 0, a wartość CHAR_MAX będzie taka sama jak wartość UCHAR_MAX. Wartość UCHAR_MAX będzie wynosić 2 ^ CHAR_BIT - 1.

Ramashalanka
źródło
9
Dodatkowa uwaga. istnieje makro CHAR_BITS, które powie ci, ile bitów mają twoje znaki.
nr
1
Pełne dane tej wspaniałej książki pochodzą z Harbison and Steele. C: A Reference Manual, Third Edition, Prentice Hall, 1991
osgx,
2
Jeśli wiesz, że pracujesz z typami znaków i wiesz, że język wymaga, aby miały one rozmiar 1, dlaczego dobrze jest zawsze umieszczać nadmiarowy rozmiar sizeof (char)?
1
(a) i (c) mają znacznie poważniejsze konsekwencje, których nie można rozwiązać, ani nawet zbliżyć się do rozwiązania; także YAGNI. Ktoś taki jak w (b) wystarczy raz powiedzieć - nie muszę ich uczyć w każdym wierszu mojego kodu. Istnieją jednak wady używania sizeof(char): jest to kolejny przedmiot do debaty / sprawdzenia / itp. w twoich konwencjach / standardach / wytycznych kodowania, marnuje mój czas na zastanawianie się, czy naprawdę znasz C i co jeszcze może być niepoprawne, zajmuje wizualną / mentalną / tekstową "przepustowość".
1
@Ramashalanka: Tak, skompilowany kod jest równoważny. Chodzi o wszystkie problemy dotyczące czytelności i innych kwestii, jak ludzie używają kodu źródłowego, o których mówię. (I FWIW, myślę, że masz tutaj przyzwoitą odpowiedź +1, po prostu uważam, że „zawsze używaj sizeof (char)” jest błędne i jest to dla mnie problem z przyciskiem skrótu, nawet jeśli jest to mały problem.)
21

Nie ma maszyn, w których sizeof(char)jest 4. To zawsze 1 bajt. Ten bajt może zawierać 32 bity, ale jeśli chodzi o kompilator C, jest to jeden bajt. Aby uzyskać więcej informacji, wskażę Ci C ++ FAQ 26.6 . Ten odsyłacz całkiem dobrze to opisuje i jestem prawie pewien, że C ++ ma wszystkie te reguły z C. Możesz również spojrzeć na comp.lang.c FAQ 8.10 dla znaków większych niż 8 bitów.

Uaktualnienie2: Ale rozmiar wyniku NIE JEST BYTEM! to jest rozmiar CHAR. A znak może mieć 2 bajty lub (może być) 7 bitów?

Tak, to bajty. Powtórzę to. sizeof(char)to 1 bajt według kompilatora C. To, co ludzie potocznie nazywają bajtem (8 bitów), niekoniecznie jest tym samym, co kompilator C nazywa bajtem. Liczba bitów w bajcie C różni się w zależności od architektury twojego komputera. Gwarantowane jest również co najmniej 8.

Michael Kristofik
źródło
3
Proszę!!! C ++ jest naprawdę INNYM językiem od C (C99). To pytanie dotyczy tylko zwykłego C.
osgx,
<strike> Co mogę zrobić, gdy komputer / procesor nie ma dostępu do 8-bitowych bajtów? Dostęp bez wyrównania jest zabroniony. </strike> (Nawet na x86 malloc zwraca wyrównane dane i alokuje pamięć w wielokrotnościach 4 bajtów.) <strike> Wtedy CHAT_BIT będzie większy niż 8. Tak, taka platforma może być raczej wyjątkowa. </ Strike >
osgx,
11
@osgx, mam tendencję do krzyczenia tak samo jak ty, kiedy ludzie próbują mieszać C i C ++. Ale myślę, że w tym przypadku jeden wpis FAQ w C ++ odnosi się równie dobrze do C.
Michael Kristofik
3
Prawidłowa nazwa dla „8 bitów” to oktet. Standard C używa słowa „bajt” dla obiektu o rozmiarze znaku. Inni mogą używać słowa „bajt” na różne sposoby, często kiedy mają na myśli „oktet”, ale w C (i C ++ lub Objective-C) oznacza to „obiekt wielkości znaku”. Znak może mieć więcej niż 8 bitów lub więcej niż jeden oktet, ale zawsze jest to jeden bajt.
gnasher729
9

PDP-10 i PDP-11 były.

Aktualizacja: nie ma kompilatorów C99 dla PDP-10.

Niektóre modele 32-bitowego procesora SHARC DSP firmy Analog Devices mają CHAR_BIT = 32, a procesor Texas Instruments DSP z TMS32F28xx ma CHAR_BIT = 16, podobno .

Aktualizacja: Istnieje GCC 3.2 dla PDP-10 z CHAR_BIT = 9 (sprawdź include / limits.h w tym archiwum).

osgx
źródło
1
Nie myl implementacji języków podobnych, ale nie-C z C. Powiedziałeś nawet: „Martwię się zgodnością ze standardem C99. Ściśle współpracuję z kompilatorami C99”.
2
@Roger: To nie fair nazywać GCC3 niezgodnym z C99, chyba że masz do czynienia z skrajnymi przypadkami, które są uważane za błędy w GCC.
Joshua,
1
@Joshua, myślę, że Roger mówi o historycznych kompilatorach K&R i pcc. Również nieuczciwe twierdzenie, że jest zgodny z C99 przed uruchomieniem zestawu testowego zgodności C99 na PDP-10, po skompilowaniu z tym portem (mogą występować błędy związane z portowaniem i samą maszyną). Ale można oczekiwać, że będzie zbliżony do standardu C99, podobnie jak GCC3.2 na x86.
osgx,
1
@Joshua: CHAR_BIT może być w C99 większy niż 8, ale sizeof (char) musi nadal wynosić 1 (a ta odpowiedź była zupełnie inna, kiedy zostawiłem ten komentarz). Nie nazywam GCC3 niezgodnym, a C89 stawia tutaj takie same wymagania, BTW. Zacytowałem ten tekst, aby powiedzieć, że osgx jest tym, który martwi się o zgodność z C99 i używa kompilatorów C99, więc dlaczego martwi się o kompilatory inne niż C99?
2
Autor PDP-10 GCC tutaj. CHAR_BIT to 9, ale sizeof (char) to nadal 1.
Lars Brinkhoff