Почему так мало C-компиляторов?


72

Си является одним из наиболее широко используемых языков в мире. На его долю приходится огромная доля существующего кода, и он продолжает использоваться для огромного количества нового кода. Он пользуется популярностью среди пользователей, настолько широко портирован, что возможность запуска C является для многих неофициальным определением платформы , и его поклонники хвалят за то, что он «маленький» язык с относительно чистым набором функций.

Так где же все компиляторы?

На рабочем столе есть (реально) два : GCC и Clang. Подумав об этом несколько секунд, вы наверняка вспомните, что Intel тоже существует. Есть горстка других, слишком непонятных для обычного человека, чтобы назвать их и почти повсеместно не заботящихся о поддержке недавней языковой версии (или часто даже четко определенного языкового подмножества, просто «подмножество»). Половина членов этого списка - исторические сноски; большинство остальных очень специализированы и все еще не реализуют полный язык. Очень немногие действительно кажутся открытыми.

Scheme и Forth - другие маленькие языки, которые так любят их поклонники - вероятно, имеют больше компиляторов, чем настоящие пользователи. Даже что-то вроде SML имеет на выбор более «серьезные» реализации, чем C. Принимая во внимание, что объявление о новом (незаконченном) компиляторе C, нацеленном на проверку, на самом деле видит некоторые довольно негативные ответы, и ветеранские реализации пытаются получить достаточно участников, чтобы даже догнать C99.

Почему? Реализация C так сложно? Это не C ++. Имеют ли пользователи просто весьма искаженное представление о том, к какой группе сложности они относятся (т.е. что они на самом деле ближе к C ++, чем к Scheme)?


61
MSVC все еще считается, по крайней мере, компилятором C89. Возможно, даже более популярный, чем Intel.
Rufflewind

22
В Википедии перечислено довольно много компиляторов Си. Они очень распространены, когда вы попадаете во встроенное царство.

113
сколько компиляторов вам нужно, чтобы скомпилировать ваш код на C?
Брайан Чен

76
Вопрос основан на ложной предпосылке. Analog Devices, armcc, компилятор C Брюса, кросс-компилятор Bare-C, компилятор Borland, компилятор clang, компилятор Cosmic C, компилятор CodeWarrior, компилятор dokto, компилятор Ericsson, и я даже не вышел из Первые пять букв алфавита еще нет. Существует безумно большое количество компиляторов Си. Вопрос в том, почему так мало C-компиляторов, если мы не считаем эти несколько десятков настоящими C-компиляторами. Вы определили подавляющее большинство компиляторов Си как неинтересные, поэтому их не так много.
Эрик Липперт

19
Вопросы «почему» - плохие вопросы для этого сайта в лучшие времена, а «почему нет?» вопросы хуже. Если бы я встретил тебя на вечеринке и спросил: «Так почему бы тебе не участвовать в гонках на парусниках?» Я думаю, вы по праву найдете это странным вопросом. Вам не нужно предоставлять оправдание НЕ заниматься технически сложным, физически рискованным и очень дорогим хобби. Написание любого нетривиального программного обеспечения является дорогостоящим, сложным и рискованным и поэтому требует огромного мотиватора. Лучше было бы спросить: «Почему так много C-компиляторов?» Удивительно, что их больше одного.
Эрик Липперт

Ответы:


153

Сегодня вам нужен реальный компилятор C, чтобы быть оптимизирующим компилятором , особенно потому, что C больше не является языком, близким к аппаратному, потому что текущие процессоры невероятно сложны ( вышли из строя , конвейерны , суперскалярны , со сложными кэшами и TLB , следовательно, нуждающийся в расписании инструкций и т.д ...). Современные процессоры x86 не похожи на процессоры i386 прошлого века, даже если они оба могут выполнять один и тот же машинный код. Посмотрите, что C не является языком низкого уровня (ваш компьютер не быстрый PDP-11), статья Дэвида Чисналла.

Мало кто использует наивные неоптимизирующие компиляторы C, такие как tinycc или nwcc , поскольку они создают код, который в несколько раз медленнее, чем может дать оптимизирующий компилятор.

Кодирование оптимизирующего компилятора сложно. Обратите внимание, что и GCC, и Clang оптимизируют некое «исходное от языка» представление кода (Gimple для GCC, LLVM для Clang). Сложность хорошего компилятора C не находится на этапе анализа!

В частности, создание компилятора C ++ не намного сложнее, чем создание компилятора C: анализ C ++ и преобразование его в некоторое внутреннее представление кода является сложным (потому что спецификация C ++ сложна), но хорошо понятна, но части оптимизации еще более сложны. сложный (внутри GCC: оптимизация среднего уровня, нейтральность исходного языка и целевого процессора, составляют большую часть компилятора, а остальная часть балансируется между интерфейсами для нескольких языков и фонами для нескольких процессоров). Следовательно, большинство оптимизирующих компиляторов C также способны компилировать некоторые другие языки, такие как C ++, Fortran, D, ... Части GCC, специфичные для C ++, составляют около 20% от компилятора ...

Кроме того, C (или C ++) настолько широко используется, что люди ожидают, что их код будет компилируемым, даже если он не совсем соответствует официальным стандартам, которые недостаточно точно определяют семантику языка (поэтому каждый компилятор может иметь свою собственную интерпретацию этого). Посмотрите также на проверенный CompCert C-компилятор и статический анализатор Frama-C , которые заботятся о более формальной семантике C.

Оптимизация - это феномен длинного хвоста : реализовать несколько простых оптимизаций легко, но они не сделают компилятор конкурентоспособным! Вам необходимо реализовать множество различных оптимизаций, а также организовать и разумно их объединить, чтобы получить конкурентоспособный компилятор. Другими словами, реальный оптимизирующий компилятор должен быть сложным программным обеспечением. Кстати, и GCC, и Clang / LLVM имеют несколько внутренних специализированных генераторов кода C / C ++. И то, и другое - огромные звери (несколько миллионов строк исходного кода, скорость роста которых составляет несколько процентов в год) с большим сообществом разработчиков (несколько сотен человек, работающих в основном полный рабочий день или по крайней мере половину рабочего дня).

Обратите внимание, что нет (насколько мне известно) многопоточного C-компилятора, даже если некоторые части компилятора могут выполняться параллельно (например, внутрипроцедурная оптимизация, распределение регистров, планирование инструкций ...). И параллельной сборки с make -jне всегда достаточно (особенно с LTO ).

Кроме того, трудно получить финансирование на кодирование компилятора C с нуля, и такие усилия должны длиться несколько лет. Наконец, большинство компиляторов C или C ++ на сегодняшний день являются свободным программным обеспечением (больше не существует рынка для новых проприетарных компиляторов, продаваемых стартапами) или, по крайней мере, являются монопольными товарами (такими как Microsoft Visual C ++ ), и для компиляторов почти требуется свободное программное обеспечение ( потому что они нуждаются в участии многих различных организаций).

Я был бы рад получить финансирование для работы над компилятором C с нуля как свободное программное обеспечение, но я не настолько наивен, чтобы верить, что это возможно сегодня!


14
(there is no more a market for proprietary compilersРасскажите об этом команде Visual Studio ...
Мейсон Уилер

18
У Microsoft есть монополия. Я имел в виду, что небольшие компании, разрабатывающие новые компиляторы Си, не будут продавать их много. Можете ли вы назвать недавнего проприетарного конкурента MSVC?
Василий Старынкевич,

12
В мире высокопроизводительных вычислений существует множество проприетарных компиляторов. PGCC, NAG и ICC являются наиболее широко используемыми.
Davidmh

37
@MasonWheeler: VS раздается бесплатно (как в пиве). Несвободные версии добавляют инструменты, но компилятор C в VS2013 одинаков во всех версиях. Там просто нет рынка, даже для них.
MSalters

3
Но и GCC, и LLVM работают с гораздо более низкими представлениями, а также оптимизируют код C ++ & C (& Ada & Fortran, для GCC). Напротив, я бы сказал, что C ++ требует большей оптимизации (особенно при компиляции кода с использованием его STL), чем C!
Василий Старынкевич,

70

Я хотел бы оспорить ваше базовое предположение, что существует только небольшое количество реализаций языка Си.

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

Прежде всего, существует компилятор, который, вероятно, полностью затмевает как GCC, так и Clang на настольном компьютере: Microsoft Visual C. Несмотря на достижения OSX и Linux на настольных компьютерах, а также долю рынка, которую iOS и Android «украли» В отличие от бывших традиционных пользователей настольных компьютеров, Windows по-прежнему является доминирующей настольной ОС, и большинство программ Windows C для настольных компьютеров, вероятно, скомпилированы с использованием инструментов Microsoft.

Традиционно каждый производитель ОС и каждый производитель чипов имели свои собственные компиляторы. Microsoft, как поставщик ОС, имеет Microsoft Visual C. IBM, как поставщик ОС, так и поставщик микросхем, имеет XLC (системный компилятор по умолчанию для AIX и компилятор, с помощью которого компилируются и AIX, и i / OS). , У Intel есть свой компилятор. У Sun / Oracle есть собственный компилятор в Sun Studio.

Кроме того, существуют производители высокопроизводительных компиляторов, такие как PathScale и The Portland Group, чьи компиляторы (и библиотеки OpenMP) используются для перебора чисел.

Цифровой Марс также все еще в бизнесе. Я считаю, что Уолтер Брайт обладает уникальным отличием, будучи единственным человеком на планете, который сумел создать компилятор С ++ производственного качества (в основном) сам.

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

Почетное упоминание обращается к TruffleC , интерпретатору C (!), Работающему на JVM (!), Написанной с использованием среды интерпретатора Truffle AST, которая всего на 7% медленнее, чем GCC и Clang (в зависимости от того, что быстрее в любом конкретном тесте) по всему Тест на знание компьютерных языков, причем быстрее, чем на микробенчмарках. Используя TruffleC, команда Truffle смогла получить свою версию JRuby + Truffle для выполнения расширений Ruby C быстрее, чем фактическая реализация C Ruby!

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


1
За пределами Microsoft Visual C большинство упомянутых компиляторов C используются редко.
Василий Старынкевич

6
MSVC - большой компилятор C ++, но для C он сложен в использовании и навсегда застрял в C89; компиляторы микроконтроллеров обычно специфичны для конкретной цели, застряли в C89 и причудливы; TruffleC пока недоступен (но это интересно, спасибо). Pathscale и Digital Mars больше похожи на контрпримеры, которые я искал, хотя.
Леушенко

8
@ Марио, я имею в виду не то, что C89 сломан, но C89 не является современной формой языка; и это означает, что существует меньше актуальных компиляторов .
Леушенко

6
@Leushenko MSVC не постоянно застревает в C89. Были некоторые обсуждения, и следует добавить больше функций C99. Для начала, большая часть библиотеки C99 поддерживается начиная с MSVC 2015, а также некоторые языковые функции (в основном это то, что нужно для C ++ 11).
Морвенн

5
@Morwenn: политика Microsoft, по-видимому, заключается в том, что C99 не решает проблем, которые C ++ еще не решил, и что, если вы занимаетесь системным программированием, вам следует использовать C-подобное подмножество C ++ (все, что не требует времени выполнения или где вы не можете контролировать, куда компилятор собирается помещать вещи - важно, если вам нужно убедиться, что код или данные не выгружаются из состояний, где подкачка отключена). Единственными возможностями C99 будут вещи, которые требуются в более поздних спецификациях C ++, и те, которые легко реализовать.
Майк Диммик

8

Сколько компиляторов вам нужно?

Если у них разные наборы функций, вы создаете проблему переносимости. Если они коммодитизированы, вы выбираете «по умолчанию» (GCC, Clang или VS). Если вы заботитесь о последних 5% производительности, у вас есть эталонный тест.

Если вы занимаетесь языком программирования для отдыха или в исследовательских целях, скорее всего, это будет более современный язык. Отсюда распространение игрушечных компиляторов для Scheme и ML. Хотя OCaml, похоже, набирает обороты для не игрушечных неакадемических целей.

Обратите внимание, что это сильно зависит от языка. По сути, Java имеет набор инструментов Sun / Oracle и GNU. В Python есть различные компиляторы, ни один из которых не пользуется уважением по сравнению со стандартным интерпретатором. Rust и Go имеют по одной реализации. C # имеет Microsoft и Mono.


1
Очевидно, что есть более интересные причины для разработки компилятора ML ... Я просто подумал, что сообщество C, вероятно, на три порядка больше, уравновесит этот эффект. Но вы можете быть правы, 1000 * 0все еще 0.
Леушенко

Создание нового компилятора часто связано с фрагментацией сообщества (вызванной или вызывающей). Например, разделитель egcs vs gcc разделяет. Кроме того, совместимость с источником С имеет тенденцию быть ниже 100%.
pjc50

@ pjc50: способ написания стандарта эффективно подразделяет C на несколько непересекающихся диалектов, основанных на таких вещах, как базовый тип int, и требует, чтобы разные компиляторы интерпретировали один и тот же исходный код по-разному.
Суперкат

5
Я считаю, что Go имеет две реализации ( 6g/ 8g/… toolchain и gccgo). Раньше также была очень интересная коммерческая реализация, называемая erGo, которая была: а) родной реализацией Go для Windows в то время, когда ни gccgo, ни оригинальный компилятор Go не работали очень хорошо на Windows, б) компанией, ставящей на Go, долго еще до того, как он стал 1.0, и в) первая реализация Go написана на Go (gccgo и 6g / 8g написаны на C). Однако и проект, и компания исчезли еще до того, как вышли из закрытой бета-версии.
Йорг Миттаг

6

C / C ++ является уникальным среди скомпилированных языков в том смысле, что он имеет 3 основных реализации общей спецификации.

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

И я думаю, что javascript - единственная причина, по которой вам нужно указывать «скомпилированный».


2
Метка «C» применяется для ряда различных языков; некоторые определяют код uint16_t a=48000u; unsigned uint32_t b=(a*a)/2;как присвоение bзначению 8192. Некоторые определяют его как присвоение 1152000000. Большинство в настоящее время рассматривают его как неопределенное поведение и, скорее всего, сохранят 3299483648, но не дают никаких обещаний в этом отношении.
Суперкат

1
@supercat: Ах, странный вопрос с переполнением и целочисленными правилами продвижения. Это зависит от использования 2или, 2uпо-видимому.
Zan Lynx

1
@ZanLynx: я не думаю, что бывают случаи, когда 2 против 2u имеют законное значение; единственный известный мне случай, когда это может иметь значение, связан с неопределенным поведением как 2, так и 2u.
суперкат

3
@supercat: как бы вы получили неопределенное поведение /2u? Определяется переполнение без знака (как по модулю 2 ^ N для N, определенного реализацией), но деление не может даже переполниться.
MSalters

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

5

Так какой у вас целевой язык?

Компиляторы SML часто нацелены на C или что-то вроде LLVM (или, как видно из вашей ссылки, JVM или JavaScript).

Если вы компилируете C, это не потому, что вы собираетесь в JVM. Вы идете к чему-то хуже, чем C. Гораздо хуже. И затем вы получаете возможность дублировать этот незначительный ад несколько раз для всех ваших целевых платформ.

И конечно, C - это не C ++, но я бы сказал, что он ближе к C ++, чем Scheme. У него есть собственное подмножество неопределенной поведенческой злости (я смотрю на вас размером встроенных типов). И если вы испортите эти мелочи (или сделаете это «правильно», но неожиданно), то у вас есть десятилетия существующего кода на жизненно важных системах, которые скажут вам, насколько вы ужасны. Если вы испортите SML-компилятор, он просто не будет работать - и кто-то может заметить. Когда - нибудь.


SML / NJ и PolyML компилируются в машинный код ...
Басиле Старинкевич

2
Как размер int "Неопределенное поведение"? И почему в любом случае UB станет обузой для производителей компиляторов? Единственным реальным бременем для разработчиков компиляторов является то, что int-ширина определяется реализацией, а не задается, поэтому вы должны задокументировать, что вы сделали.
MSalters

@MSalters На самом деле, создатели компиляторов для установленной платформы несут бремя сопоставления того, что делали другие, предшествовавшие им. Иногда это документируется и стандартизируется, иногда нет. Легко узнать, каков размер int, но сложнее найти, что делается со значениями регистров и где хранятся аргументы при вызове функции (которая может изменяться в зависимости от типов аргументов и возвращаемого типа функции), правил структурирования макета, и т.д.
Random832

@MSalters Большинство людей ожидают, intчто они будут 32 или 64- битными, но могут быть и 16-битными. Нетрудно получить число вне диапазона, [−32767, +32767]а intпереполнение - UB. Также char/ shortповышается int или unsigned int зависит от того, intможет ли представлять каждое значение исходного типа, что может дополнительно инициировать преобразование из intв, unsigned intесли операнды имели разные типы и были преобразованы по-разному, плюс потенциально другое преобразование, когда вы присваиваете результат переменной ,
Доваль

@MSalters Существует достаточно свободы в размере стандартных типов и достаточных неявных преобразований, поэтому я бы поспорил, что практически для любой нетривиальной программы на С есть выбор допустимых целочисленных размеров, которые приведут к неправильным действиям или неопределенным поведение.
Доваль
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.