Есть ли машины, где 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макросы)

Update2: Но результат sizeof НЕ БАЙТОВ! это размер CHAR. А char может быть 2 байтовым, а может быть 7 битным?

Update3: Хорошо. Все машины есть sizeof(char) == 1. Но какие машины есть CHAR_BIT > 8?

osgx
источник
4
Меня беспокоит соответствие стандарту C99. Я тесно сотрудничаю с компиляторами C99
osgx
2
Поскольку Unicode становится еще более важным, могут появиться нестандартные компиляторы, которые используют символы Unicode как char(вместоwchar .). Даже если стандарт говорит, что это sizeof(char)должно быть 1, я бы не стал полагаться на это предположение.
Chip Uni
14
нет компиляторов C, где sizeof (char) не равно 1, unicode или нет.
6
@Chip: sizeof(char)всегда 1, даже если char 32-битный (как это происходит в некоторых системах). У C много забавных бородавок.
Ник Бастин
2
Все версии стандарта C требуют, чтобы CHAR_BIT было не менее 8; вы не можете иметь CHAR_BIT == 7 и соответствовать стандарту. Однако для машин вполне возможно иметь CHAR_BIT> 8. Я полагаю, что старые машины 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 или signed char (или их квалифицированную версию), результат равен 1.

Изменить: не часть вашего вопроса, но для интереса Харбисона и Стила, 3-е изд. (pre c99) стр. 148:

Под единицей хранения понимается объем памяти, занимаемый одним символом; charпоэтому размер объекта типа равен 1.

Изменить: в ответ на ваш обновленный вопрос актуален следующий вопрос и ответ от Харбисона и Стила (там же, пример 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 и Харбисона и Стила.

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

Оператор sizeof возвращает размер (в байтах) его операнда.

поэтому в сочетании с приведенной выше цитатой, байты из 8 бит и char4 из этих байтов невозможны: для c99 байт совпадает сchar .

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

Их значения, определяемые реализацией, должны быть равны или больше [выделено мной] по величине показанных с тем же знаком.

- количество бит для наименьшего объекта, не являющегося битовым полем (байт)

 **CHAR_BIT 8**

- минимальное значение для объекта типа signed char

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

- максимальное значение для объекта типа signed char

**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, который скажет вам, сколько бит у ваших символов.
1
Полные данные этой великой книги принадлежат Харбисону и Стилу. C: Справочное руководство, третье издание, Prentice Hall, 1991
osgx
2
Если вы знаете, что работаете с типами char, и знаете, что язык требует, чтобы они имели размер 1, почему лучше всегда помещать избыточный sizeof (char)?
1
(а) и (в) имеют гораздо более серьезные разветвления, которые нельзя решить или даже приблизиться к решению; также ЯГНИ. Кому-то, как в (b), просто нужно сказать один раз - мне не нужно учить их в каждой строчке моего кода. Однако есть недостатки в использовании sizeof(char): это еще один предмет для обсуждения / проверки и т. Д. в ваших соглашениях / стандартах / рекомендациях по кодированию, я трачу время на размышления о том, действительно ли вы знаете C, а что еще может быть неправильным, занимает визуальную / мысленную / текстовую «полосу пропускания».
1
@Ramashalanka: Да, скомпилированный код эквивалентен. Я говорю о проблемах с удобочитаемостью и о том, как люди используют исходный код. (И FWIW, я думаю, у вас есть приличный ответ +1 здесь, я просто считаю, что «всегда используйте sizeof (char)», что является ошибочным и проблемой для меня, даже если это небольшая проблема.)
21

Нет машин, где sizeof(char)равно 4. Это всегда 1 байт. Этот байт может содержать 32 бита, но для компилятора C это один байт. Для получения более подробной информации я на самом деле собираюсь указать вам на C ++ FAQ 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). Этот вопрос касается только простого C.
osgx 07
<strike> Что делать, если компьютер / процессор не могут получить доступ к 8-битным байтам? Невыровненный доступ запрещен. </strike> (Даже на x86 malloc возвращает выровненные данные и выделяет память кратно 4 байтам.) <strike> Тогда CHAT_BIT будет больше 8. Да, такая платформа может быть довольно особенной. </ Strike >
osgx 07
11
@osgx, я так же часто кричу, как и ты, когда люди пытаются смешать C и C ++. Но я думаю, что в данном случае одна запись в часто задаваемых вопросах по C ++ применима и к C.
Майкл Кристофик,
3
Правильное имя для «8 бит» - октет. Стандарт C использует слово «байт» для объекта размером с символ. Другие могут использовать слово «байт» по-разному, часто когда оно означает «октет», но в C (и C ++ или Objective-C) оно означает «объект размером с символ». Символ может содержать более 8 бит или более одного октета, но всегда один байт.
gnasher729
9

PDP-10 и PDP-11 были.

Обновление: компиляторов C99 для PDP-10 вроде нет.

Некоторые модели Analog Devices 32-битного DSP SHARC имеют CHAR_BIT = 32, и Texas Instruments DSP от TMS32F28xx имеют CHAR_BIT = 16, по сообщениям .

Обновление: есть GCC 3.2 для PDP-10 с CHAR_BIT = 9 (проверьте include / limits.h в этом архиве).

osgx
источник
1
Не путайте реализации языков, похожих на C, но не C, с C. Вы даже сказали: «Меня беспокоит соответствие стандарту C99. Я тесно сотрудничаю с компиляторами C99».
2
@Roger: Несправедливо называть GCC3 несовместимым с C99, если только вы не имеете дело с крайними случаями, которые считаются ошибками в GCC.
Джошуа
1
@Joshua, я думаю, что Роджер говорит об исторических компиляторах K&R и pcc. Также несправедливо утверждать, что он совместим с C99 до того, как набор тестов на соответствие C99 будет запущен на PDP-10, когда он скомпилирован с этим портом (могут быть ошибки при переносе и на самой машине). Но можно ожидать, что он будет близок к стандарту C99, как и GCC3.2 на x86.
osgx 07
1
@Joshua: CHAR_BIT в C99 может быть больше 8, но sizeof (char) все равно должен быть 1 (и этот ответ сильно отличался, когда я оставил этот комментарий). Я не называю GCC3 несовместимым, и C89 предъявляет здесь то же требование, BTW. Я процитировал этот текст, чтобы сказать, что именно osgx беспокоится о совместимости с C99 и использует компиляторы C99, так почему он беспокоится о компиляторах, отличных от C99?
2
Автор PDP-10 GCC здесь. CHAR_BIT равно 9, но sizeof (char) по-прежнему 1.
Lars Brinkhoff