На каких платформах есть что-то кроме 8-битного символа? - PullRequest
130 голосов
/ 20 января 2010

Время от времени кто-то на SO указывает, что char (он же «байт») не обязательно 8 бит .

Кажется, что 8-битный char почти универсален. Я бы подумал, что для основных платформ необходимо иметь 8-битный char, чтобы обеспечить его жизнеспособность на рынке.

И сейчас, и исторически, какие платформы используют char, который не является 8-битным, и почему они отличаются от "нормальных" 8-битных?

Когда вы пишете код и думаете о кроссплатформенной поддержке (например, для библиотек общего пользования), какое внимание стоит уделить платформам с не 8-битной char?

В прошлом я сталкивался с некоторыми ЦСП Analog Devices, для которых char равен 16 битам. Полагаю, что DSP - это немного нишевая архитектура. (Опять же, в то время, когда ассемблер с ручным кодированием легко справлялся с тем, что могли делать доступные компиляторы C, поэтому я не особо разбирался в C на этой платформе.)

Ответы [ 12 ]

76 голосов
/ 20 января 2010

char также 16 бит на ЦСП Texas Instruments C54x, который появился, например, в OMAP2. Существуют и другие DSP с 16 и 32 битами char. Я думаю, что даже слышал о 24-битном DSP, но я не могу вспомнить, что, поэтому, возможно, я представил это.

Другое соображение заключается в том, что POSIX обязывает CHAR_BIT == 8. Так что, если вы используете POSIX, вы можете принять это. Если кому-то позже понадобится перенести ваш код в почти реализованную POSIX, то случится так, что у вас будут функции, которые вы используете, но другого размера char, это их неудача.

В общем, я думаю, что почти всегда легче обойти проблему, чем думать об этом. Просто наберите CHAR_BIT. Если вам нужен точный 8-битный тип, используйте int8_t. Ваш код с шумом не сможет скомпилироваться в реализациях, которые его не предоставляют, вместо того, чтобы молча использовать размер, который вы не ожидали. По крайней мере, если я столкнусь с делом, когда у меня были веские основания полагать, что это так, я бы это утверждал.

36 голосов
/ 20 января 2010

Когда вы пишете код и думаете о кроссплатформенной поддержке (например, для библиотек общего пользования), какое внимание стоит уделить платформам с не 8-битным символом?

Дело не столько в том, что «стоит задумываться» о чем-то, сколько об играх по правилам.Например, в C ++ стандарт говорит, что все байты будут иметь «как минимум» 8 бит.Если ваш код предполагает, что байты имеют ровно 8 бит, вы нарушаете стандарт.

Теперь это может показаться глупым - « конечно все байты имеют 8 бит!», Я слышуты говоришь.Но многие очень умные люди полагались на предположения, которые не были гарантиями, и тогда все сломалось.История изобилует такими примерами.

Например, большинство разработчиков начала 90-х предполагали, что конкретная задержка тактирования неактивных процессоров, занимающая фиксированное количество циклов, займет фиксированное количество тактовых часов, поскольку большинство потребительских процессоровбыли примерно эквивалентны по мощности.К сожалению, компьютеры стали быстрее очень быстро.Это привело к появлению коробок с кнопками «Турбо», цель которых, по иронии судьбы, состояла в том, чтобы замедлить работу компьютера, чтобы в игры, использующие технику задержки, можно было играть с разумной скоростью.


Один комментатор спросил, где в стандарте написано, что char должен иметь не менее 8 бит.Он находится в разделе 5.2.4.2.1 .В этом разделе определяется CHAR_BIT, число битов в наименьшем адресуемом объекте, и значение по умолчанию равно 8. В нем также говорится:

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

Таким образом, любое число, равное 8 или выше, подходит для замены реализацией в CHAR_BIT.

31 голосов
/ 20 января 2010

Машины с 36-битной архитектурой имеют 9-битные байты. Согласно Википедии, машин с 36-битной архитектурой включают в себя:

  • Корпорация цифрового оборудования PDP-6/10
  • IBM 701/704/709/7090/7094
  • UNIVAC 1103 / 1103A / 1105/1100/2200,
18 голосов
/ 20 января 2010

Некоторые из которых мне известны:

  • DEC PDP-10: переменные, но чаще всего 7-битные символы упакованы по 5 на 36-битное слово, или же 9-битные символы, 4за слово
  • Мэйнфреймы управляющих данных (CDC-6400, 6500, 6600, 7600, Cyber ​​170, Cyber ​​176 и т. д.) 6-битовые символы, упакованные по 10 на 60-битное слово.
  • Unisysмэйнфреймы: 9 бит / байт
  • Windows CE: просто не поддерживает тип `char` - вместо этого требуется 16-битный wchar_t
15 голосов
/ 28 ноября 2013

Нет такого понятия, как полностью переносимый код.: -)

Да, могут быть различные размеры байтов / символов.Да, могут быть реализации C / C ++ для платформ с очень необычными значениями CHAR_BIT и UCHAR_MAX.Да, иногда можно написать код, который не зависит от размера символа.

Однако практически любой реальный код не является автономным.Например, вы можете писать код, который отправляет двоичные сообщения в сеть (протокол не важен).Вы можете определить структуры, которые содержат необходимые поля.Чем вы должны его сериализовать.Простое двоичное копирование структуры в выходной буфер не является переносимым: обычно вы не знаете ни порядка байтов для платформы, ни выравнивания членов структуры, поэтому структура просто хранит данные, но не описывает способ сериализации данных..

Хорошо.Вы можете выполнять преобразования порядка байтов и перемещать элементы структуры (например, uint32_t или аналогичные), используя memcpy в буфер.Почему memcpy?Поскольку существует множество платформ, на которых невозможно записать 32-разрядную (16-разрядную, 64-разрядную - без разницы), если целевой адрес не выровнен должным образом.

Итак, вы ужесделано много для достижения переносимости.

А теперь последний вопрос.У нас есть буфер.Данные с него отправляются в сеть TCP / IP.Такая сеть предполагает 8-битные байты.Вопрос в том, какого типа должен быть буфер?Если ваши символы 9-битные?Если они 16-битные?24?Может быть, каждый символ соответствует одному 8-битному байту, отправленному в сеть, и используются только 8 бит?Или, может быть, несколько сетевых байтов упакованы в 24/16/9-битные символы?Это вопрос, и трудно поверить, что есть один ответ, который подходит для всех случаев.Многое зависит от реализации сокетов для целевой платформы.

Итак, о чем я говорю.Обычно код может быть относительно легко сделан переносимым до определенной степени .Это очень важно сделать, если вы ожидаете использовать код на разных платформах.Однако улучшение переносимости сверх этой меры - это то, что требует больших усилий и часто дает мало , поскольку реальный код почти всегда зависит от другого кода (реализация сокета в примере выше).Я уверен, что для примерно 90% кода способность работать на платформах с байтами, отличными от 8-битных, практически бесполезна, поскольку она использует среду, привязанную к 8-битным.Просто проверьте размер байта и выполните утверждение времени компиляции.Вам почти наверняка придется много переписывать для очень необычной платформы.

Но если ваш код очень "автономен" - почему бы и нет?Вы можете написать его так, чтобы он позволял разные размеры байтов.

9 голосов
/ 20 января 2010

Многие чипы DSP имеют 16- или 32-битные char. TI обычно делает такие чипы , например .

9 голосов
/ 20 января 2010

Похоже, что вы все еще можете купить IM6100 (т.е. PDP-8 на чипе) со склада.Это 12-битная архитектура.

5 голосов
/ 20 января 2010

Например, языки программирования C и C ++ определяют байт как «адресуемую единицу данных, достаточно большую, чтобы вместить любой элемент базового набора символов среды выполнения» (п. 3.6 стандарта C).Поскольку целочисленный тип данных C char должен содержать не менее 8 битов (пункт 5.2.4.2.1), байт в C по меньшей мере способен содержать 256 различных значений.Различные реализации C и C ++ определяют байт как 8, 9, 16, 32 или 36 битов

В кавычках http://en.wikipedia.org/wiki/Byte#History

Не уверен, однако, о других языках.

http://en.wikipedia.org/wiki/IBM_7030_Stretch#Data_Formats

Определяет байт на этом компьютере как переменную длину

4 голосов
/ 10 марта 2010

Семейство DEC PDP-8 имело 12-битное слово, хотя вы обычно использовали 8-битный ASCII для вывода (в основном на Teletype). Однако был также 6-битный код символа, который позволял вам кодировать 2 символа в одном 12-битном слове.

3 голосов
/ 24 августа 2012

Какое внимание стоит уделить платформам с не 8-битным символом?

магические числа встречаются, например, при переключении;

большинство из них могут быть обработаны довольно просто используя CHAR_BIT и, например, UCHAR_MAX вместо 8 и 255 (или аналогичных).

надеюсь, ваша реализация определяет это:)

это "общие" проблемы .....

другая косвенная проблема - скажем, у вас есть:

struct xyz {
   uchar baz;
   uchar blah;
   uchar buzz; 
}

это может «только» занять (в лучшем случае) 24 бита на одной платформе, но может занять, например, 72 бита в другом месте .....

если каждый uchar содержит «битовые флаги» и каждый uchar имеет только 2 «значимых» бита или флага, которые вы в настоящее время используете, и вы только организовали их в 3 учаров для «ясности», тогда это может быть относительно «более расточительным», например, на платформе с 24-битными учарами .....

ничто не может решить битовые поля, но у них есть другие вещи, на которые нужно обратить внимание для ....

в этом случае, только одно перечисление может быть способом получения «самого маленького» целое число, которое вам действительно нужно ....

возможно, не реальный пример, но такие вещи "кусают" меня при портировании / воспроизведении некоторого кода .....

просто тот факт, что если учар в три раза больше того, что "обычно" ожидается, 100 таких структур могут тратить много памяти на некоторых платформах ..... где "обычно" это не имеет большого значения .....

так что все еще можно «сломать» или в этом случае «очень быстро потратить много памяти» из-за в предположении, что учар "не очень расточительный" на одной платформе относительно доступной оперативной памяти, чем на другой платформе .....

проблема может быть более заметной, например, для целых, а также других типов, например у вас есть какая-то структура, которая нуждается в 15 битах, поэтому вы вставляете ее в int, но на какой-то другой платформе int составляет 48 бит или что-то еще .....

"обычно" вы можете разбить его на 2 учара, но, например, с 24-битным учаром вам нужен только один .....

так что enum может быть лучшим "общим" решением ....

зависит от того, как вы получаете доступ к этим битам:)

итак, могут быть "недостатки дизайна", которые поднимают их голову .... даже если код все еще может работать / работать нормально, независимо от размер учара или уинт ...

есть вещи, на которые стоит обратить внимание, даже если в вашем коде нет "магических чисел" ...

надеюсь, что это имеет смысл:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...