Список платформ, поддерживаемых стандартом C - PullRequest
24 голосов
/ 04 ноября 2011

Кто-нибудь знает о каких-либо платформах, поддерживаемых стандартом C, для которых все еще ведутся активные разработки, но которые:

  • не дополняют 2 или
  • целочисленная ширинане 32 бит или 64 бита или
  • у некоторых целочисленных типов есть биты заполнения или
  • , если вы работали на машине дополнения 2, битовая комбинация со знаковым битом 1 и всеми битами значения ноль не являетсядействительное отрицательное число или
  • целочисленное преобразование из подписанного в беззнаковое (и наоборот) происходит не посредством дословного копирования битовых комбинаций, или
  • смещение вправо целого числа не является арифметическим сдвигом или
  • количество битов значения в типе без знака не является количеством битов значения в соответствующем типе со знаком + 1 или
  • преобразование из более широкого типа int в меньший тип происходит не путем усечения самого левогобиты, которые не соответствуют

РЕДАКТИРОВАТЬ: Альтернативно, если в период с 1995 по 1998 год были платформы, которые повлияли на решение C99 включитьВыше, но были прекращены, я был бы заинтересован в них также.

РЕДАКТИРОВАТЬ: Обоснование имеет это сказать о битах заполнения:

Биты заполнения являются пользовательскимидоступно в виде целого числа без знака.Например, предположим, что машина использует пару 16-битных шорт (каждая со своим собственным знаковым битом) для создания 32-битного целого числа, а знаковый бит нижнего короткого замыкания игнорируется при использовании в этом 32-битном целом.Затем, как 32-разрядное знаковое целое, существует бит дополнения (в середине 32-разрядного), который игнорируется при определении значения 32-разрядного знакового целого.Но если этот 32-битный элемент обрабатывается как 32-битное целое число без знака, то этот бит заполнения виден программе пользователя.Комитету C было сказано, что есть машина, которая работает таким образом, и это одна из причин, по которой биты заполнения были добавлены в C99.

В сносках 44 и 45 упоминается, что биты четности могут бытьбиты заполнения.Комитет не знает ни о каких машинах с доступными для пользователя битами четности в целом числе.Таким образом, комитет не знает ни о каких машинах, которые обрабатывают биты четности как биты заполнения.

Таким образом, другой вопрос, что это за машина, о которой упоминал C99?

РЕДАКТИРОВАТЬ: Кажется,что C99 рассматривает возможность удаления поддержки дополнения 1 и величины со знаком: http://www.open -std.org / jtc1 / sc22 / wg14 / www / docs / n868.htm http://www.open -std.org/jtc1/sc22/wg14/www/docs/n873.htm (поиск по 6.2.6.2)

Ответы [ 7 ]

12 голосов
/ 05 ноября 2011

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

В частности, вы не можете полагаться на арифметику двух дополненийВы INT_MAX+1 == INT_MIN.Например, gcc 4.6.0 оптимизирует следующее в бесконечный цикл:

#include <stdio.h>
int main() {
     int i = 0;
     while (i++ >= 0)
          puts(".");
     return 0;
}

EDIT : Подробнее об оптимизации переполнения со знаком и GCC см. Здесь .

11 голосов
/ 14 ноября 2011

Я недавно работал в компании, которая все еще использовала версию PDP-10 и порт GCC для этой платформы. У 10, которые мы использовали, было несколько атрибутов, которые вы перечислили:

  • Целые числа не 32 или 64 бит, они имеют ширину 36 бит.
  • Биты заполнения используются для некоторых представлений. Для целых чисел с расширенной точностью (например, типа long long) базовое представление было 72-разрядным, в котором каждое из 36-разрядных слов имело знаковый бит.

В дополнение к вышеупомянутым необычным атрибутам, была проблема, что у машины было несколько различных механизмов адресации байтов. Байты с шириной в диапазоне 6-12 бит могут быть адресованы с помощью специальных битов в самом адресе, которые указывают, какая ширина и выравнивание слов использовались. Чтобы представить символ *, можно использовать представление, которое будет адресовать 8-битные байты, все из которых выровнены по левому краю в слове, оставляя 4-битные в каждом 36-битном слове, которые не были адресованы вообще. В качестве альтернативы можно использовать 9-битные байты, которые будут равномерно вписываться в 36-битное слово. Оба таких подхода имели свои недостатки для переносимости, но в то время, когда я ушел, было сочтено более практичным использовать 8-битные байты из-за взаимодействия с сетями TCP / IP и стандартными устройствами, которые часто думают в терминах 16, 24 или 32. -битные поля, которые также имеют базовую структуру 8-битных байтов.

Насколько я знаю, эта платформа все еще используется в продуктах в этой области, и в этой компании есть разработчик компилятора, который обновляет относительно последние версии GCC, чтобы обеспечить дальнейшее развитие C на этой платформе.

11 голосов
/ 09 ноября 2011

Около десяти лет назад нам пришлось портировать нашу встроенную базу данных C на процессор DSP, который оказался главным процессором автомобильной стереосистемы. В худшем случае это была 24-битная машина: sizeof(char) == sizeof(int) == sizeof(void*) == 1, что составляло 24 бита. Мы назвали ветвь, которая имела дело с этим портом "24-битный ад".

С тех пор мы портировали нашу библиотеку на многие платформы, но ни одна из них не была такой странной. Они все еще могут существовать (дешевые 24-битные DSP-чипы теперь стали еще дешевле), которые можно найти в недорогих устройствах, где простота программирования является отдаленной секундой после низкой спецификации материалов (BOM). Если подумать, я думаю, что мы столкнулись с машиной, в которой смещение вправо от целого числа без знака не обязательно вставляет нулевые биты. Тем не менее, крайне нестандартные арифметические правила для платформы гарантируют сложный, подверженный ошибкам перенос программного обеспечения на нее, что значительно увеличивает затраты на разработку программного обеспечения. В какой-то момент преобладает здравомыслие и соблюдаются стандарты.

Я подозреваю, что причиной появления этих правил в C99 является их присутствие в C89 и более ранние итерации языка. Не забывайте, что когда C был изобретен, компьютеры были намного разнообразнее, чем сегодня. Были доступны процессоры с разделением по битам, где вы могли добавить столько бит, сколько захотите, просто добавив микросхемы. А до C вам приходилось кодировать на ассемблере или беспокоиться о том, где именно в ОЗУ будет находиться ваш код и т. Д.

C был значительным шагом вперед с точки зрения переносимости, но он должен был охватывать разнообразные системы, отсюда и самые общие правила. Спустя 20 лет, когда появилась Java, она имела историческое преимущество, позволяя ей заранее объявлять, какими должны быть большие примитивные типы, что делает все намного проще, если выбор Java является здравым.

Я знаю, что вы в основном спрашиваете о целых числах, но я столкнулся с некоторыми странностями, когда дело доходит до указателей. Ранние компьютеры Macintosh имели 32-битные процессоры (Motorola 68000), но только 24-битные шины памяти. Таким образом, 0x00123456 и 0xFF123456 ссылаются на одну и ту же ячейку памяти, поскольку процессор обрезает верхние 8 бит при обращении к ОЗУ. Инженеры Apple использовали эти биты для хранения метаданных о памяти, на которую указывал указатель. Таким образом, при сравнении указателей нужно было сначала маскировать верхние биты. И не начинайте меня с архитектуры сегментированной памяти x86. :)

Поскольку мы занимаемся этой темой, взглянем на стандарт кодирования MISRA , который предпочитают производители автомобилей, которым требуется максимальная мобильность и безопасность. Также посмотрите на Восторг Хакера Генри С. Уоррена, в котором есть тонны полезных хитростей.

6 голосов
/ 05 ноября 2011

Даже если эти машины древние, все еще существует активное программирование сообщества для PDP-8, большинство, но не все, используют моделирование: PDP-8 в качестве примера .И эта машина, AFAIK, использует 12-битные целые числа!

6 голосов
/ 04 ноября 2011

Мои два цента.Пожалуйста, не вините сильно, это из моего опыта, я не теоретик:

  • не дополняет 2

Все изсуществующие процессоры дополняют 2

  • целочисленная ширина не 32 или 64 бита

Существуют также 8- и 16-битные архитектуры.Хороший пример - 8-битные микроконтроллеры AVR.

  • у некоторых целочисленных типов есть биты заполнения

Мне не известна любая система, которая колодки целых чисел.Плавающие числа - это отдельная история.

  • , если вы работали на машине дополнения 2, битовая комбинация со знаковым битом 1 и всеми нулевыми битами значения не является допустимым отрицательным числом
  • целочисленное преобразование из подписанного в беззнаковое (и наоборот) происходит не путем дословного копирования битовых комбинаций
  • смещение вправо целого не является арифметическим смещением
  • количество битов значения в типе без знака не являетсячисло битов значения в соответствующем типе со знаком + 1
  • преобразование из более широкого типа int в меньший тип не является усечением самого левого бита, который не соответствует

Все вышеперечисленное - никому не известно, и я предполагаю, что такой машины нет.

4 голосов
/ 04 ноября 2011

Компилятор cc65 для Commodore C64, похоже, обновился еще в прошлом году.

3 голосов
/ 04 ноября 2011

Старая поговорка (я забыл атрибуцию) гласит, что

нет такой вещи, как переносимый код

Но только этонекоторые коды, которые были портированы.

Вы не должны заботиться о написании переносимого кода, вы должны заботиться о написании кода, который будет легко переносить на другие платформы.

Кроме того, используя толькоСтандарт C дает вам не много полезных вещей.Стандарты Posix дают вам гораздо больше.

...