Чи існують машини, де sizeof (char)! = 1, або принаймні CHAR_BIT> 8?


93

Чи є машини (або компілятори), де sizeof(char) != 1?

Чи зазначає стандарт C99, що sizeof(char)при впровадженні відповідності стандартам ПОВИННО бути рівно 1? Якщо так, будь ласка, дайте мені номер розділу та посилання.

Оновлення: Якщо у мене є машина (ЦП), яка не може адресувати байти (мінімальне читання - 4 байти, вирівняне), але лише 4-х байт ( uint32_t), чи може компілятор для цієї машини визначити sizeof(char)4? sizeof(char)буде 1, але char матиме 32 біти ( CHAR_BITмакроси)

Оновлення2: Але sizeof результату НЕ БАЙТ! це розмір CHAR. А char може бути 2-байтовим, або (може бути) 7-бітовим?

Оновлення3: Добре. Всі машини мають sizeof(char) == 1. Але які машини є CHAR_BIT > 8?


4
Мене турбує відповідність стандарту C99. Я тісно співпрацюю з компіляторами C99
osgx

2
Оскільки Unicode стає ще важливішим, можуть з’явитися нестандартні компілятори, які використовують символи Unicode як char(замість wchar.) Навіть якщо стандарт говорить, що це sizeof(char)має бути 1, я б не покладався на це припущення.
Chip Uni

14
немає компіляторів C, де sizeof (char) не дорівнює 1, юнікод чи ні.
nos

6
@Chip: sizeof(char)завжди 1, навіть якщо char 32-бітний (як це відбувається в деяких системах). C має безліч веселих бородавок.
Нік Бастін,

2
Для всіх версій стандарту C потрібно, щоб CHAR_BIT становив принаймні 8; ви не можете мати CHAR_BIT == 7 і відповідати стандартам. Однак для машин цілком доцільно мати CHAR_BIT> 8. Я вважаю, що машини Old Cray мали ( sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)на тих; я не пам’ятаю, чи sizeof(int) == sizeof(long)було CHAR_BIT 32 чи 64; я сподіваюся, що було 32, і я sizeof(long) == 1теж думаю . (Ви можете знайти посилання на посібник із Cray C , але не доступ до нього в Інтернеті ).
Джонатан Леффлер,

Відповіді:


91

Це завжди одне в C99, розділ 6.5.3.4:

При застосуванні до операнда, який має тип char, unsigned char або подписаний char (або його кваліфіковану версію), результат дорівнює 1.

Редагувати: не частина вашого запитання, але для зацікавлення від Harbison and Steele, 3rd edition. (до c99) с. 148:

За одиницю зберігання приймається обсяг пам’яті, зайнятий одним символом; тому розмір об’єкта типу char1.

Редагувати: У відповідь на ваше оновлене запитання є актуальним наступне запитання та відповідь Харбісона та Стіла (там же, Вип. 4 розділу 6):

Чи допустимо мати реалізацію C, в якій тип charможе представляти значення від -2,147,483,648 до 2,147,483,647? Якщо так, то що буде sizeof(char) під цим впровадженням? Який би був найменший і найбільший діапазони типу int?

Відповідь (там же, с. 382):

Для реалізації дозволено (якщо марнотратне) використовувати 32 біти для представлення типу char. Незалежно від реалізації, значення sizeof(char)завжди дорівнює 1.

Хоча це конкретно не стосується випадку, коли, скажімо, байти складають 8 бітів і charє 4 з цих байтів (насправді неможливо з визначенням c99, див. Нижче), той факт, що sizeof(char) = 1завжди видно зі стандарту c99 та Harbison and Steele.

Edit: Насправді (це у відповідь на ваше запитання UPD 2), наскільки c99 стурбований sizeof(char) знаходиться в байтах, з розділу 6.5.3.4 знову:

Оператор sizeof видає розмір (у байтах) його операнда

отже, у поєднанні з цитатою вище, байти по 8 бітів і charяк 4 з цих байт неможливі: для c99 байт - це те саме, що a char.

У відповідь на вашу згадку про можливість 7-бітного char: це неможливо в c99. Відповідно до розділу 5.2.4.2.1 стандарту мінімум становить 8:

Їх значення, визначені реалізацією, мають бути рівними або більшими [мій наголос] за величиною до тих, що показані, з однаковим знаком.

- кількість бітів для найменшого об'єкта, який не є бітовим полем (байт)

 **CHAR_BIT 8**

- мінімальне значення для об'єкта типу, підписаного символом

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

- максимальне значення для об'єкта типу, підписаного символом

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

- максимальне значення для об'єкта типу unsigned char

**UCHAR_MAX 255//28−1** 

- мінімальне значення для об'єкта типу char

**CHAR_MIN**    see below 

- максимальне значення для об'єкта типу char

**CHAR_MAX**    see below

[...]

Якщо значення об'єкта типу char при використанні у виразі обробляється як підписане ціле число, значення CHAR_MIN має бути таким самим, як значення SCHAR_MIN, а значення CHAR_MAX має бути таким же, як значення SCHAR_MAX. В іншому випадку значення CHAR_MIN має дорівнювати 0, а значення CHAR_MAX має бути таким же, як значення UCHAR_MAX. Значення UCHAR_MAX має дорівнювати 2 ^ CHAR_BIT - 1.


9
Додаткова примітка. є макрос CHAR_BITS, який повідомляє вам, скільки бітів складають ваші символи.
nos

1
Повні дані цієї чудової книги - « Харбісона та Стіла». C: Довідковий посібник, третє видання,
Прентис

2
Якщо ви знаєте, що працюєте з типами символів, і знаєте, що мова вимагає, щоб вони мали розмір 1, чому це гарна ідея завжди розміщувати надмірний sizeof (char)?

1
(а) та (в) мають набагато серйозніші наслідки, які не можна вирішити, або навіть наблизитись до вирішення; також ЯГНІ. Комусь, як у (b), просто потрібно сказати один раз - мені не потрібно вчити їх у кожному рядку мого коду. Однак є недоліки використання sizeof(char): це ще один пункт для обговорення / перевірки / тощо. у ваших конвенціях / стандартах / керівних принципах кодування марно витрачає час на роздуми, чи справді ви знаєте C і що ще може бути неправильним, займає візуальну / ментальну / пропускну здатність текстового рядка.

1
@Ramashalanka: Так, скомпільований код еквівалентний. Це все, що стосується читабельності та того, як люди використовують вихідний код, про що я кажу. (І FWIW, я думаю, що у вас тут є гідна відповідь +1, я просто вважаю, що "завжди використовувати sizeof (char)"), і це проблема для мене, навіть якщо це невеличка проблема.)

21

Немає машин, де sizeof(char)є 4. Це завжди 1 байт. Цей байт може містити 32 біти, але, що стосується компілятора C, це один байт. Щоб отримати докладнішу інформацію, я фактично вкажу вам на C ++ 26.6 . Це посилання охоплює це досить добре, і я впевнений, що C ++ отримав усі ці правила від C. Ви також можете переглянути comp.lang.c FAQ 8.10 для символів, що перевищують 8 біт.

Upd2: Але sizeof результату НЕ БАЙТ! це розмір CHAR. І char може бути 2 байтовим, або (може бути) 7 бітовим?

Так, це байти. Дозвольте сказати ще раз. sizeof(char)- це 1 байт відповідно до компілятора C. Те, що люди в розмовній формі називають байтом (8 біт), не обов'язково те саме, що компілятор C називає байтом. Кількість бітів у байті C змінюється залежно від архітектури вашої машини. Також гарантовано буде принаймні 8.


3
Будь ласка !!! C ++ - це справді РІЗНА мова від мови C (C99). Це питання стосується лише простого С.
osgx

<strike> Що я можу зробити, коли машина / процесор не може отримати доступ до 8-бітових байтів? Доступ без вирівнювання заборонено. </strike> (Навіть на x86 malloc повертає вирівняні дані та виділяє пам'ять умноженням на 4 байти.) <strike> Тоді CHAT_BIT буде більше 8. Так, така платформа може бути досить особливою. </ Strike >
osgx

10
@osgx, я схильний кричати так само, як ти щойно, коли люди намагаються змішати C та C ++. Але я думаю, що в цьому випадку один запитання щодо поширених запитань на C ++ однаково добре стосується і C.
Michael Kristofik

3
Правильна назва "8 біт" - октет. Стандарт C використовує слово "байт" для об'єкта розміром із символ. Інші можуть вживати слово "байт" по-різному, часто коли вони мають на увазі "октет", але в C (і C ++, або Objective-C) це означає "об'єкт розміром із символ". Символ може складати більше 8 бітів або більше одного октету, але це завжди один байт.
gnasher729

9

PDP-10 та PDP-11 були.

Оновлення: компіляторів C99 для PDP-10 як немає.

Повідомляється, що деякі моделі 32-розрядних DSP-процесорів SHARC аналогових пристроїв мають CHAR_BIT = 32, а DSP Texas Instruments від TMS32F28xx - CHAR_BIT = 16, як повідомляється .

Оновлення: Існує GCC 3.2 для PDP-10 з CHAR_BIT = 9 (перевірте include / limit.h в цьому архіві).


1
Не плутайте реалізації подібних, але не C-мов, і мови C. Ви навіть сказали: "Мене турбує відповідність стандартам C99. Я тісно співпрацюю з компіляторами C99".

2
@Roger: Нечесно називати GCC3 несумісним із C99, якщо ви не маєте справу з надзвичайними випадками, які в GCC вважаються помилками.
Джошуа

1
@ Джошуа, я думаю, Роджер говорить про історичні компілятори K&R та ПКК. Також нечесно стверджувати, що він відповідає стандарту C99 до запуску тесту на відповідність стандарту C99 на PDP-10, коли він компілюється з цим портом (можуть виникати помилки від портування та від самої машини). Але можна очікувати, що він буде наближений до стандарту C99, як це робить GCC3.2 на x86.
osgx

1
@Joshua: CHAR_BIT дозволено, в C99, перевищувати 8, але sizeof (char) все одно повинен бути 1 (і ця відповідь значно відрізнялася, коли я залишив цей коментар). Я не називаю GCC3 невідповідним, і C89 висуває ту саму вимогу, до речі. Я цитував цей текст, щоб сказати, що osgx турбується про відповідність C99 і використовує компілятори C99, то чому він турбується про компілятори, які не є C99?

2
Автор PDP-10 GCC тут. CHAR_BIT - 9, але розмір (char) - все ще 1.
Ларс Брінкхофф
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.