В настоящее время C считается языком низкого уровня , но еще в 70-х он считался языком низкого уровня? Был ли термин даже в употреблении тогда?
Многие популярные языки более высокого уровня не существовали до середины 80-х и далее, поэтому мне интересно, изменилась ли природа низкого уровня за эти годы.
programming-languages
c
history
joeyfb
источник
источник
Ответы:
Чтобы ответить на исторические аспекты вопроса:
Философия дизайна объясняется на языке программирования Си, написанном Брайаном Керниганом и дизайнером Си Деннисом Ричи, «K & R», о котором вы, возможно, слышали. В предисловии к первому изданию говорится
и введение говорит
Список продолжается некоторое время, прежде чем текст продолжается:
(У меня есть только второе издание с 1988 года, но комментарий ниже указывает, что цитируемый текст такой же, как и в первом издании 1978 года.)
Итак, да, термины «высокий уровень» и «низкий уровень» использовались в то время, но С был разработан так, чтобы находиться где-то между ними в спектре. Можно было написать код на C, который был бы переносимым на аппаратные платформы, и это было основным критерием того, считался ли язык в то время высоким уровнем. Однако в C отсутствовали некоторые функции, которые были характерны для языков высокого уровня, и это было дизайнерское решение в пользу простоты.
источник
Это зависит от вашего определения языка высокого и низкого уровня. Когда был разработан язык C, все, что было более высокого уровня, чем ассемблер, считалось языком высокого уровня. Это низкий бар, чтобы очистить. Позже эта терминология перешла к тому, что в настоящее время некоторые считают, что даже Java является языком низкого уровня.
Даже в языковой среде высокого уровня 70-х годов стоит отметить, что уровень C довольно низок. Язык C в основном представляет собой B плюс простую систему типов, а B - это не более чем удобный процедурный / структурированный синтаксический уровень для сборки. Поскольку система типов является ретро-версией поверх нетипизированного языка B, в некоторых местах вы все еще можете опускать аннотации типов, и
int
это будет предполагаться.С сознательно не учитывает дорогие или трудные для реализации функции, которые уже были хорошо известны в то время, такие как
C имеет некоторые интересные особенности:
Во время разработки C другие инновационные языки, такие как COBOL, Lisp, ALGOL (на разных диалектах), PL / I, SNOBOL, Simula и Pascal, уже были опубликованы и / или широко использовались для конкретных проблемных областей. Но большинство из этих существующих языков предназначались для программирования на мэйнфреймах или были академическими исследовательскими проектами. Например, когда ALGOL-60 был впервые разработан как универсальный язык программирования, необходимых технологий и компьютерных наук для его реализации еще не было. Некоторые из них (некоторые диалекты ALGOL, PL / I, Pascal) также предназначались для низкоуровневого программирования, но, как правило, имели более сложные компиляторы или были слишком безопасными (например, без указателей без ограничений). Паскалю не хватает хорошей поддержки массивов переменной длины.
По сравнению с этими языками C отказывается от «элегантных» и дорогих функций, чтобы быть более практичным для низкоуровневой разработки. C никогда прежде не был исследовательским проектом языкового дизайна. Вместо этого это был ответвление разработки ядра Unix на миникомпьютере PDP-11, который был сравнительно ограничен в ресурсах. Для своей ниши (минималистский низкоуровневый язык для написания Unix с однопроходным компилятором, который легко переносить) C абсолютно преуспел - и спустя более 45 лет он по-прежнему остается языком системного программирования.
источник
%r10
как «статический указатель цепи», о чем вы и говорите. Для C это всего лишь еще один регистр с нуля, но я думаю, что Паскаль будет его использовать. (Вложенные функции GNU C используют его для передачи указателя на внешнюю область, когда такая функция не встроена (например, если вы создаете указатель на нее, чтобы компилятор создавал батут машинного кода в стеке): приемлемость обычного использование r10 и r11 )a = b;
чтобы скопировать всю структуру, как вы можете в ISO C89. Таким образом, в ранних C определяемые пользователем типы были определенно вторым классом и могли передаваться только по ссылке как аргументы функции. Отвращение C к массивам, а также Почему C ++ поддерживает членское присвоение массивов внутри структур, но не в целом?В начале 1970-х C был ослепительно свежим воздухом, использующим современные конструкции настолько эффективно, что всю систему UNIX можно было переписать с языка ассемблера на C с незначительным пространством или снижением производительности. В то время многие современники называли его языком высокого уровня.
Авторы C, в первую очередь Деннис Ритчи, были более осмотрительными, и в статье в Техническом журнале Bell System говорится, что «C не является языком высокого уровня». С кривой улыбкой и намерением быть провокационным, Деннис Ричи сказал бы, что это язык низкого уровня. Главной целью проекта C было сохранить язык близко к машине, но при этом обеспечить мобильность, то есть независимость от машины.
Для получения дополнительной информации обратитесь к оригинальной статье BSTJ:
Спасибо, Деннис. Покойся с миром.
источник
Как я писал в другом месте на этом сайте, когда кто-то упоминал шаблон управления памятью malloc / free как «низкоуровневое программирование»
Для контекста, это было в начале 90-х, задолго до того, как вышел C.
источник
malloc()
непосредственного вызоваbrk(2)
илиmmap(2)
управления полученной памятью самостоятельно. Это огромная PITA без какой-либо мыслимой выгоды (если только вы не реализуете подобную malloc вещь), но вы можете это сделать.Многие ответы уже ссылались на ранние статьи, в которых говорилось что-то вроде «C не является языком высокого уровня».
Однако я не могу устоять перед накоплением: многие, если не большинство или все HLL в то время - Algol, Algol-60, PL / 1, Pascal - обеспечивали проверку границ массивов и обнаружение переполнения чисел.
В последний раз я проверял, что переполнение буфера и целочисленные значения были основной причиной многих уязвимостей. ... Да, все еще так ...
Ситуация с динамическим управлением памятью была более сложной, но все же Malloc / free в стиле C был большим шагом назад с точки зрения безопасности.
Так что, если ваше определение HLL включает «автоматически предотвращает множество ошибок низкого уровня», то состояние кибербезопасности, к сожалению, будет совсем другим, возможно, лучше, если бы C и UNIX не случались.
источник
popcnt
.Рассмотрим более старые и намного более высокие языки, предшествовавшие C (1972):
Фортран - 1957 (не намного выше уровня С)
Лисп - 1958
Кобол - 1959
Фортран IV - 1961 г. (не намного выше уровня С)
PL / 1 - 1964
APL - 1966
Плюс язык среднего уровня, такой как RPG (1959), в основном язык программирования, заменяющий основанные на платах системы записи единиц измерения.
С этой точки зрения C казался языком очень низкого уровня, только немного выше макросборщиков, которые использовались на мэйнфреймах в то время. В случае мэйнфреймов IBM для доступа к базе данных использовались макросы на ассемблере, такие как BDAM (базовый метод доступа к диску), поскольку интерфейсы базы данных не были портированы на Cobol (в то время), что привело к наследованию сочетания сборок и Программы Cobol до сих пор используются на мэйнфреймах IBM.
источник
Ответ на ваш вопрос зависит от того, о каком языке C он спрашивает.
Язык, описанный в Справочном руководстве С 1974 года Денниса Ритчи, был языком низкого уровня, который предлагал некоторые удобства программирования языков высокого уровня. Диалекты, производные от этого языка, также, как правило, были языками программирования низкого уровня.
Однако, когда был опубликован стандарт С 1989/1990 гг., Он не описывал язык низкого уровня, ставший популярным для программирования на реальных машинах, а вместо этого описывал язык более высокого уровня, который мог бы быть - но не обязателен - - реализовано в терминах более низкого уровня.
Как отмечают авторы стандарта C, одна из вещей, которая сделала язык полезным, заключалась в том, что многие реализации можно рассматривать как ассемблеры высокого уровня. Поскольку C также использовался в качестве альтернативы другим языкам высокого уровня, и поскольку многим приложениям не требовалась способность делать то, чего не могли делать языки высокого уровня, авторы стандарта позволили реализациям вести себя произвольным образом. если программы пытались использовать низкоуровневые конструкции. Следовательно, язык, описанный в Стандарте C, никогда не был языком программирования низкого уровня.
Чтобы понять это различие, рассмотрим, как язык Ричи и C89 будут просматривать фрагмент кода:
на платформе, где «char» равен 8 битам, «int» равен 16 битам с прямым порядком байтов, «float» равен 32 битам, и структуры не имеют специальных требований к заполнению или выравниванию, поэтому размер «struct foo» составляет 8 байтов.
На языке Ричи поведение последнего оператора будет принимать адрес, сохраненный в «p», добавлять к нему 3 * 8 + 2 [то есть 26] байта и извлекать 16-битное значение из байтов по этому адресу и следующему добавьте единицу к этому значению, а затем запишите это 16-битное значение в те же два байта. Поведение будет определяться как действие на 26-й и 27-й байты, следующие за байтом по адресу p, независимо от того, какой тип объекта там хранится.
На языке, определенном Стандартом C, в случае, если * p идентифицирует элемент «struct foo []», за которым следуют как минимум еще три полных элемента этого типа, последний оператор добавит один к члену y из третий элемент после * р. Поведение не будет определяться Стандартом ни при каких других обстоятельствах.
Язык Ричи был языком программирования низкого уровня, потому что, хотя он позволял программисту использовать абстракции, такие как массивы и структуры, когда это было удобно, он определял поведение в терминах базовой структуры объектов в памяти. В отличие от этого, язык, описанный в C89 и более поздних стандартах, определяет вещи в терминах абстракции более высокого уровня и определяет только поведение кода, которое соответствует этому. Качественные реализации, подходящие для низкоуровневого программирования, будут вести себя полезно в большем количестве случаев, чем предписано Стандартом, но не существует «официального» документа, определяющего, что реализация должна делать, чтобы подходить для таких целей.
Таким образом, язык Си, изобретенный Деннисом Ритчи, является языком низкого уровня и был признан таковым. Тем не менее, язык, изобретенный Комитетом по стандартам C, никогда не был языком низкого уровня в отсутствие предоставленных реализацией гарантий, выходящих за рамки мандатов Стандарта.
источник