Полагаю, это действительно скорее исторический, чем технический вопрос.Короткий ответ: был один, своего рода.Это не заняло.Длинный ответ довольно длинен, в зависимости от того, сколько деталей вы хотите рассмотреть.
C стар.Я имею в виду, Python также старый, но C действительно старый.Деннис Ритчи взломал первые версии этого вместе в Bell Labs в конце 1960-х годов, и он сделал это так, чтобы ему не пришлось писать UNIX на ассемблере или B (который сейчас является забытым языком системного программирования того времени, который имелнекоторые недостатки C были сделаны для устранения).
Возможно, сегодня это совершенно иной подход, чем проектирование языка: C был написан с целью написания UNIX.Никто не сел и не разработал C для разработки красивого и чистого языка системного программирования;эти ребята хотели написать операционную систему и создали инструмент, который позволял им делать это более просто.
Однако этот компилятор Bell Labs C был своего рода эталонной реализацией, в которой C был, по сути, тем, что написала команда Cв их компилятор.Затем появился переносной компилятор C, который должен был упростить перенос C на новые платформы, и книга под названием «Язык программирования C» (она же неофициальная спецификация K & R C), и C стал популярным, и все было хорошо.А потом все усложнилось.
C стал популярным в то время, когда все еще было ... давайте будем благотворительны и скажем "есть место для улучшений".Конечно, это было;У каждого языка всегда есть возможности для совершенствования.Для начала не было настоящей стандартной библиотеки.Аргументы функций не проверялись во время компиляции, функции не могли возвращать void
или struct
s, такого рода вещи.По краям все еще было неровно.
Но теперь была не только Лаборатория Белла, о нет.Теперь были десятки поставщиков, все с их адаптациями компиляторов pcc или homegrown, и множеством отличных, а иногда и не очень хороших идей о способах улучшения C.Они также были менее заинтересованы в разработке языка, чем в разработке инструмента, который упростил бы их фактические задания.Поэтому они написали свои собственные расширения для языка, и иногда они плохо сочетались с расширениями, которые придумали другие люди.
Теперь на этом этапе легко разобраться с вопросом и спросить, почему они этого не сделали.просто лучше координируйте развитие языка, но на самом деле все было не так просто.Интернет еще не существовал, поэтому они не могли просто настроить канал IRC для обсуждения вещей, а также ... ну, языки программирования были не единственной вещью, которая была грязной по сравнению с сегодняшним днем.
Сегодня большинство компьютеров довольно похожи.Мы все представляем отрицательные целые числа как дополнение к двум, байты почти всегда имеют ширину 8 бит, указатели - это просто адреса памяти.В то время это было не так, и если учесть, что, когда C был стандартизирован, все еще оставались машины, которые использовали свое дополнение или величину со знаком, вы понимаете, почему переполнение со знаком не определено в C. Вы когда-нибудь виделиC-код для старой программы DOS?У них была такая концепция ближнего и дальнего указателей, потому что старые 16-битные компьютеры x86 нуждались в специальных регистрах сегментации для адресации более 64 КБ ОЗУ.Несколько компиляторов создали для этого расширения C, но, поверьте мне, вы очень, очень рады, что C сегодня не включает эту концепцию.Советы создали сбалансированный троичный компьютер, хотя я не уверен, имел ли он поддержку Си.Короче говоря, аппаратный ландшафт также был запутанным, и это очень важно для языка, близкого к металлическому.
Итак, каждый делал то, что должен был, и в целом (хотя и не всегда), как мог, но язык обязательно расходился.Языковое ядро было в конечном итоге стандартизировано в 1989 году (когда Гробовщик ... держится не в том году), чтобы вернуть некоторое подобие порядка, и спустя несколько лет после этого компиляторы начали сходиться в нем.Тем не менее, некоторые из старых расширений никогда не исчезнут, потому что обратная совместимость всегда является проблемой - подумайте о том, как быстро был принят Python 3 - и есть некоторые проблемы, которые необходимо решить, чтобы языкбыть полезным, но не может быть разумно записано в спецификацию, потому что они не переносимы, такие как соглашения о вызовах.
И вот, у вас это есть.Причина того, что C имеет спецификацию языка, а не эталонную реализацию, в основном историческая и отчасти из-за тонкостей различных машин, на которых он должен работать.
Полагаю, можно было бы разработать официальную эталонную реализацию(по крайней мере, для нескольких распространенных платформ), но я также считаю, что его ценность будет несколько ограничена.В конце концов, стандарт C должен оставить неопределенным ряд вещей, потому что он не может знать точную природу базовой машины, поэтому все другие реализации будут вести себя только как эталонная реализация, пока код, который вы вводите в него, корректен,Для правильно сформированного кода обычные реализации C (т.е. gcc, clang, MSVC) обычно ведут себя одинаково, поэтому вы можете использовать любую из них.