NB существовал настолько кратко, что полное его описание не было написано.Он предоставил типы
int
и
char
, их массивы и указатели на них, объявленные в стиле, типизированном
int i, j;
char c, d;
int iarray[10];
int ipointer[];
char carray[10];
char cpointer[];
Семантика массивов осталась точно такой же, как в B и BCPL: объявления
iarray
и
carray
создают ячейки, динамически инициализированные со значением, указывающим на первую последовательность из 10 целых чисел и символов соответственно.Объявления для
ipointer
и
cpointer
опускают размер, чтобы утверждать, что никакое хранилище не должно выделяться автоматически.Внутри процедур интерпретация указателей в языке была идентична интерпретации переменных массива: объявление указателя создавало ячейку, отличающуюся от объявления массива только тем, что программист должен был назначить референт вместо того, чтобы компилятор выделял пространство иинициализировать ячейку.
Значения, хранящиеся в ячейках, привязанных к массиву и именам указателей, были машинными адресами, измеренными в байтах, соответствующей области хранения.Следовательно, косвенное обращение к указателю подразумевает отсутствие затрат времени выполнения для масштабирования указателя от смещения до байта.С другой стороны, машинный код для подписки массива и арифметики указателей теперь зависел от типа массива или указателя: для вычисления
iarray[i]
или
ipointer+i
подразумевалось масштабирование сложения i по размеру указанного объекта.
Эта семантика представляла собой легкий переход от B, и я экспериментировал с ними в течение нескольких месяцев.Проблемы стали очевидны, когда я попытался расширить нотацию типов, особенно для добавления структурированных (записей) типов.Кажется, что структуры должны отображаться интуитивно понятным образом в память машины, но в структуре, содержащей массив, нет подходящего места для хранения указателя, содержащего основание массива, или какого-либо удобного способа упорядочить его.инициализируется.Например, записи каталога ранних систем Unix могут быть описаны в C как
struct {
int inumber;
char name[14];
};
Я хотел, чтобы структура не merely для характеристики абстрактного объекта, а также для описания набора битов, которые могут быть прочитаны из каталога.Где компилятор может скрыть указатель на
name
, которого требует семантика?Даже если бы структуры рассматривались более абстрактно, а пространство для указателей могло бы быть каким-то образом скрыто, как я мог бы решить техническую проблему правильной инициализации этих указателей при выделении сложного объекта, возможно, такого, который указывал структуры, содержащие массивы, содержащие структуры на произвольную глубину?
Решение представляет собой решающий скачок в эволюционной цепочке между типизированным BCPL и типизированным C. Он устраняет материализацию указателя в хранилище и вместо этого вызывает создание указателя при упоминании имени массивав выражении.Правило, которое сохранилось в сегодняшнем C, состоит в том, что значения типа массива, когда они появляются в выражениях, преобразуются в указатели на первый из объектов, составляющих массив. Это изобретение позволило использовать большинствосуществующий код B, чтобы продолжать работать, несмотря на основной сдвиг в семантике языка.Несколько программ, которые присвоили новые значения имени массива для настройки его происхождения - возможно, в B и BCPL, бессмысленно в C - были легко восстановлены.Что еще более важно, новый язык сохранил последовательное и работоспособное (если необычное) объяснение семантики массивов, одновременно открывая путь к более полной структуре типов.