C. Почему ANSI указал только шесть символов для минимального количества значащих символов во внешнем идентификаторе?

У меня есть вопрос относительно раздела 5.2.4.1 Ограничения перевода в первом American National Standard for Programming languages - C, также известном как ANSI/ISO 9899-1990, ISO/IEC 9899.1990 (E), C89 и т. д. Проще говоря, первый Стандарт ANSI С.

Что такого странного говорит стандарт?

В нем печально известно, что для обработки требуется только соответствующий компилятор C, и я цитирую:

5.2.4.1 Ограничения на перевод

  • 6 значащих начальных символов во внешнем идентификаторе

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

Даже стандартная библиотека предписывает функции с более длинными именами, longjmp, tmpfile, strncat. Последнее, strncat, показывает, что им пришлось немного потрудиться, чтобы изобрести имена библиотек, в которых начальные шесть символов были уникальными, вместо, возможно, более логичного strcatn, которое столкнулось бы с strcat.

Почему это все еще проблема для меня?

Мне нравятся старые компьютеры. Я пытаюсь писать программы, которые будут компилироваться и хорошо работать на платформах до C99, чего иногда не существует на моих любимых мишенях. Возможно, мне также нравится пытаться действительно следовать стандарту. Я многое узнал о C99 и C11, просто копаясь в старых стандартах, пытаясь отследить причины определенных ограничений и проблем с реализацией.

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

Зачем им такое навязывать?

Они начали работу над стандартизацией где-то в начале восьмидесятых и завершили ее в 1988 или 1989 году. Даже в семидесятые и шестидесятые не было какой-либо проблемы для обработки более длинных идентификаторов.

Принимая во внимание, что любой компилятор, желающий соответствовать новому стандарту, должен быть изменен — хотя бы для обновления документации — я не вижу, как было бы неразумно со стороны ANSI поставить ногу и сказать что-то вроде Это 1989 год. уже. Вы должны обработать 31 значащий начальный символ. Это не было бы проблемой для любой платформы, даже древней.

Обратная совместимость?

Из того, что я прочитал при поиске, проблема может исходить от FORTRAN. В ответе на вопрос Какова точная роль значимых символов в C (переменных)?, Джонатан Леффлер пишет:

Часть проблемы могла быть связана с Fortran; для этого требовалась только поддержка 6-символьных имен в одном регистре, поэтому компоновщики в системах, где широко использовался Фортран, не нуждались в поддержке более длинных имен.

Мне это кажется наиболее разумным ответом на прямой вопрос Почему?. Но учитывая, что это ограничение беспокоит меня каждый раз, когда я хочу написать программу, которую теоретически можно было бы собрать на старых системах, хотелось бы узнать еще некоторые подробности.


Вопросы

  1. Немного покопавшись в треке FORTRAN, я пришел только к теориям и маханиям руками. Какие популярные платформы действительно установили ограничение в 6 символов? Есть ли сверхпопулярный компоновщик, который заставил комитет по стандартам сдвинуться с места?
  2. Я не настолько стар, чтобы интересоваться подобными подробностями, когда они обсуждались. Этот предел и его обоснование публично обсуждались и защищались? Был ли общественный резонанс или просто молчаливо проигнорировали? Вилы возле штаб-квартиры ANSI?

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


person pipe    schedule 26.06.2016    source источник
comment
Отличный вопрос. У меня такой же, спасибо, что выложили сюда!   -  person BehradKhodayar    schedule 19.05.2019


Ответы (1)


30 лет назад — я был там — подавляющее большинство мирового кода было написано на Коболе, Фортране и PL/1, и подавляющее большинство которые работали на мэйнфреймах IBM 370-й серии или совместимых компьютерах. Большая часть кода C в мире работала на мини-компьютерах DEC PDP-11 и VAX. Unix и C родились на PDP, и оборудование DEC было их оплотом.

Это был мир, из которого вышел комитет ANSI C, и в котором они рассматривали практические аспекты компоновки кода, написанного на C, с языками, которые действительно имели значение, в системах, которые действительно имели значение.

Компиляторы Fortran были компиляторами Fortran 77 и ограничивали идентификаторы 6 символами. В то время компиляторы PL/1 ограничивали внешние идентификаторы 7 символами. Системный компоновщик S/370 усек символы до 8 символов. Вовсе не случайно язык ассемблера PDP-11 требовал, чтобы символы были уникальными в пределах первых 6 символов.

Не было никаких вил на лужайке комитета ANSI C, когда он оговаривал 6 начальных значащих символов для внешних идентификаторов. Это означало, что соответствующий компилятор можно было реализовать на мейнфреймах IBM; и это не обязательно должен быть тот, для которого ассемблер PDP-11 был бы неадекватным и не должен был бы иметь возможность генерировать код, который нельзя было бы даже скомпоновать с Fortan 77. Это был совершенно бессмысленный выбор. Комитет ANSI C не мог «решиться» за изменение компоновщика мэйнфреймов IBM не больше, чем он мог бы принять закон о советской ракетной конструкции.

Это уже 1989 год. Вы должны обрабатывать 31 значащий начальный символ». Это не было бы проблемой для любой платформы, даже древней.

Вы ошибаетесь. Прокрутите закон Мура мысленно на 30 лет назад и попытайтесь представить себе, какими слабыми были компьютеры, пока работал комитет. Мэйнфрейм-компьютер, который поддерживал сотни пользователей, а также запускал все системы обработки данных крупной корпорации, обычно делал это с меньшей вычислительной мощностью, памятью и ресурсами хранения, которые у меня сегодня есть в моем старом планшете Google Nexus.

Жесткий диск IBM 3380E, 1985 год, имел емкость 5,0 ГБ и стоил около 120 тысяч долларов; 270 тысяч долларов в сегодняшних деньгах. У него была скорость передачи 24 Мбит/с, около 2% от того, что обеспечивает HD моего ноутбука. С такими параметрами каждый байт, который система должна хранить, читать или записывать, каждый оборот диска, каждый тактовый цикл, взвешиваются в итоговой строке. И так было всегда, только в большей степени. Скупая экономия памяти с точностью до байта укоренилась в практике программирования, и эти короткие общедоступные имена символов были лишь одним из укоренившихся ее выражений.

Проблема была, конечно, не в том, что хилые, баснословно дорогие мейнфреймы и мини-машины, господствовавшие в культуре и советах 1980-х, не могли поддерживать языки, компиляторы, компоновщики и методы программирования, в которых эта скупая экономия памяти (и все остальное) была отброшена. Конечно, могли бы, если бы у всех были такие устройства, как ноутбук или мобильный телефон. Чего они не могли сделать без него, так это поддержки огромных многопользовательских рабочих нагрузок, для запуска которых они были куплены. Программное обеспечение должно было быть мучительно компактным, чтобы делать так много с таким малым объемом.

person Mike Kinghan    schedule 26.06.2016
comment
Спасибо за этот удивительный ответ! Я не учёл многопользовательские мэйнфреймы, хотя я всё ещё не уверен, что это веская причина. Какой бы код ни компилировался, хранилище для внешних объявлений утонет во всем остальном, что вам нужно хранить — и в памяти, и на диске. Однако я могу понять, что в то время это могло быть расценено как причина. - person pipe; 27.06.2016
comment
Ограничение на связь часто было встроено в операционные системы, которые были выпущены гораздо раньше (например, 1964 год для мэйнфреймов). Мейнфрейм IBM хранит загрузочные модули как элементы в PDS, а имена элементов имеют ограничение в 8 символов. Это ограничение датируется 1964 годом. - person Bruce Martin; 27.06.2016
comment
MsDos/Windows использовали 8-символьные имена (+ 3-символьный тип). Долгое время более длинные имена файлов реализовывались как Fudge (с уникальным 8-символьным именем). По памяти Windows Xp (2002 ??) была первой версией, которая полностью поддерживала длинные имена файлов. До этого все системные программы должны были состоять из 8 символов или меньше. - person Bruce Martin; 27.06.2016
comment
Возникли бы какие-либо трудности с указанием синтаксиса для определения функций, чьи внутренние и внешние имена различаются (например, чтобы можно было объявить, например, double integrate (double p[]) extern "int" , чтобы указать, что функция должна быть определена в C с использованием имени интегрировать, но импортированный или экспортированный символ должен называться int [имя, которое в противном случае было бы невозможно использовать в C]? В некоторых конкретных реализациях есть такая функция, но были бы какие-то трудности со стандартным синтаксисом для нее? - person supercat; 30.06.2016
comment
@supercat Насколько я понимаю, эта изящная идея была бы вполне осуществимой, но я никогда не встречал ни одного древнего компилятора, который бы сам ее поддерживал. Людей не сильно раздражал тот факт, что внешние имена должны были быть достаточно короткими для еще более древнего компоновщика. Только после господства языка C с его революционной стандартной библиотекой внешние API-интерфейсы стали действительно популярными в разработке программного обеспечения, и люди захотели связывать множество выразительных символов. - person Mike Kinghan; 30.06.2016
comment
@MikeKinghan: я видел компиляторы с директивами #pragma для этой цели (установка внешнего имени следующего объявленного идентификатора), и я думаю, что у MSVC есть директива без pragma для этой цели. Я не могу придумать ни одной платформы, для которой компилятор не мог бы обеспечить такую ​​функциональность, если бы использование имени, не поддерживаемого платформой, сделало бы программу неправильно сформированной и не требующей диагностики. - person supercat; 30.06.2016
comment
гранулярность байтов, возможно, должна читать гранулярность битов - я имел дело с протоколами сообщений, которые кодируют менее 8-битных значений через границы байтов! - person M.M; 31.01.2017
comment
Что мешало компилятору взять исходники, дать всему короткие уникальные имена, а потом это скомпилировать? - person Aaron Franke; 30.07.2019
comment
Забавно, что старый компьютер 1989 года фактически мог обслуживать 100 пользователей, в то время как 1 часто слишком много для современного устройства. - person peterh; 08.05.2020