Почему компиляторы настолько надежны?

64

Мы ежедневно используем компиляторы, как если бы их корректность была задана, но компиляторы тоже являются программами и могут содержать ошибки Я всегда задавался вопросом об этой непогрешимой надежности. Вы когда-нибудь сталкивались с ошибкой в ​​самом компиляторе? Что это было и как вы поняли, что проблема была в самом компиляторе?

... и как же они делают компиляторы настолько надежны?

EpsilonVector
источник
16
Ну, они компилируют компилятор в нем ...
Майкл К
31
Они не безошибочны. Есть ошибки компилятора - просто они очень редки.
ChrisF
5
По мере того, как вы опускаете стек кода, ошибки становятся реже: ошибки приложений встречаются чаще, чем ошибки компилятора. Ошибки компилятора встречаются чаще, чем ошибки процессора (микрокода). Это на самом деле хорошая новость: можете ли вы представить себе, если бы это было наоборот?
Fixee
Вы могли бы кое-что узнать, наблюдая, как компилятор, который имеет много ошибок (например, sdcc!), Отличается от компилятора, такого как gcc, который намного более надежен и надежен.
Бен Джексон
5
В VC ++ 6 была ошибка.
Матин Улхак

Ответы:

97

Они проходят тщательное тестирование через тысячи и даже миллионы разработчиков.

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

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

Петер Тёрёк
источник
32
Плюс большая часть кода компилятора, вероятно, может оказаться правильной.
biziclop
@biziclop, хорошая мысль, это еще одно следствие особого характера задачи.
Петер Тёрёк
Первый полный компилятор был написан в 1957 году для языка FORTRAN Джоном Бакусом. Итак, вы видите, технологии компиляции уже более 50 лет. У нас было достаточно времени, чтобы сделать это правильно, хотя, как отмечают другие, у компиляторов есть ошибки.
leed25d
@biziclop, на самом деле, некоторые компоненты, такие как лексеры и парсеры, могут даже автоматически генерироваться из грамматики, что опять-таки снижает риск ошибок (при условии, что генератор лексера / парсера является устойчивым - как это обычно бывает, по тем же причинам, что перечислены выше) ,
Петер Тёрёк
2
@ Петер: Генераторы лексеров / парсеров, по-видимому, встречаются довольно редко в наиболее широко используемых компиляторах - большинство пишут лексеры и парсеры вручную по разным причинам, включая скорость и отсутствие достаточно умных генераторов парсеров / лексеров для рассматриваемого языка (например, C ).
61

В дополнение ко всем отличным ответам пока:

У вас есть "предвзятость наблюдателя". Вы не видите ошибок, и поэтому вы предполагаете, что их нет.

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

Вы не видите ошибок, потому что вы пишете код, который составляет 99,999% от всего остального кода, который пишут люди. Вы, вероятно, пишете совершенно нормальный, простой, четко корректный код, который вызывает методы и запускает циклы и не делает ничего фантастического или странного, потому что вы обычный разработчик, решающий обычные бизнес-задачи.

Вы не видите никаких ошибок компилятора, потому что ошибки компилятора не в простых для анализа простых сценариях нормального кода; ошибки заключаются в анализе странного кода, который вы не пишете.

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

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

static void N(ref int x){}
...
N(ref 123);

Компилятор выдает три ошибки.

  • Аргумент ref или out должен быть присваиваемой переменной.
  • Наилучшее совпадение для N (ref int x) имеет недопустимые аргументы.
  • Отсутствует «ссылка» на аргумент 1.

Очевидно, что первое сообщение об ошибке является правильным, а третье - ошибкой. Алгоритм генерации ошибок пытается выяснить, почему первый аргумент был недействительным, он просматривает его, видит, что он является константой, и не возвращается к исходному коду, чтобы проверить, был ли он помечен как «ref»; скорее он предполагает, что никто не будет достаточно глуп, чтобы пометить константу как ref, и решает, что ссылка должна отсутствовать.

Непонятно, каково правильное третье сообщение об ошибке, но это не так. На самом деле, не ясно, правильно ли второе сообщение об ошибке. Должно ли разрешение перегрузки завершиться неудачно, или «ref 123» должен рассматриваться как аргумент ref правильного типа? Теперь мне нужно подумать и обсудить это с командой по сортировке, чтобы мы могли определить правильное поведение.

Вы никогда не видели эту ошибку, потому что вы, вероятно, никогда бы не сделали что-то настолько глупое, чтобы попытаться передать 123 по ссылке. И если бы вы это сделали, вы, вероятно, даже не заметили бы, что третье сообщение об ошибке бессмысленно, поскольку первое является правильным и достаточным для диагностики проблемы. Но я стараюсь делать такие вещи, потому что я пытаюсь сломать компилятор. Если бы вы попробовали, вы бы тоже увидели ошибки.

Эрик Липперт
источник
4
Хорошие сообщения об ошибках после первого очень трудно сделать.
Конечно, должно быть лучше потратить энергию, чем сделать компиляторы полностью защищенными от дурака :)
Homde
2
@MKO: Конечно. Многие ошибки не исправляются. Иногда исправление настолько дорого, и сценарий настолько неясен, что выгоды не оправдывают затраты. И иногда достаточно людей, чтобы полагаться на «глючное» поведение, которое вы должны продолжать поддерживать.
Эрик Липперт
ммм ... ошибки, которые заканчиваются в сообщениях об ошибках, "хорошо". Всегда можно немного поковырять код, чтобы он заработал. Как насчет ошибок, в которых компилятор принимает исходный код и выдает «неправильный» предположительный вывод. Это страшно
Джанлука Геттини
7
@aij: Правильно в смысле «явно легального кода C #». Например, вы когда-нибудь писали программу, содержащую интерфейс, который унаследовал два интерфейса, где у одного интерфейса было свойство, а у другого - метод с тем же именем, что и у свойства? Быстро, не глядя на спецификации: это законно ? Теперь предположим, что у вас есть вызов этого метода; это двусмысленно ? И так далее. Люди пишут код, который не делает то, что они имеют в виду постоянно. Но лишь в редких случаях они пишут код, в котором вы должны быть специалистом по спецификациям, чтобы сказать, является ли это вообще легальным C #.
Эрик Липперт
52

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

GCC, пожалуй, самый знаменитый компилятор с открытым исходным кодом на планете, и взгляните на его базу данных ошибок: http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B%2B&resolution=-- -

Между GCC 3.2 и GCC 3.2.3 посмотрите, сколько ошибок исправлено: http://gcc.gnu.org/gcc-3.2/changes.html

Что касается других, таких как Visual C ++, я даже не хочу начинать.

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

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

оборота Fanatic23
источник
19

Я столкнулся с двумя или тремя в мой день. Единственный реальный способ обнаружить это - посмотреть на ассемблерный код.

Хотя компиляторы очень надежны по причинам, указанным другими авторами, я думаю, что надежность компилятора часто является самоокупаемой оценкой. Программисты склонны рассматривать компилятор как стандарт. Когда что-то идет не так, вы полагаете, что это ваша ошибка (потому что это 99,999% времени), и изменяете свой код, чтобы обходить проблему с компилятором, а не наоборот. Например, сбой кода при высокой настройке оптимизации, безусловно, является ошибкой компилятора, но большинство людей просто устанавливают ее немного ниже и продолжают работу, не сообщая об ошибке.

Карл Билефельдт
источник
6
+1 за «просмотр компилятора как стандартного». Я давно утверждал, что есть две вещи, которые действительно определяют язык: компилятор и стандартная библиотека. Стандартный документ - это просто документация.
Мейсон Уилер
8
@Mason: Это хорошо работает для языков с одной реализацией. Для многих языков стандарт жизненно важен. Реальное влияние состоит в том, что, если вы жалуетесь на что-то, продавец отнесется к вам серьезно, если это проблема стандартов, и отмахнется от вас, если это неопределенное поведение или что-то в этом роде.
Дэвид Торнли
2
@ Mason - Это только потому, что очень немногие языки имеют стандарты и / или которым они соответствуют. Это, кстати, IMHO, не очень хорошая вещь - для любого серьезного развития, которое, как ожидается, будет длиться более одного поколения ОС.
Ладья
1
@ Дэвид: Точнее, одна доминирующая реализация. Borland определяет Pascal, а Microsoft - C # независимо от того, что говорят ANSI и ECMA.
Ден04
4
Сбои кода на C, C ++ или Fortran при высокой оптимизации - гораздо более неправильный входной код, чем ошибки компилятора. Я очень часто работаю с последними и предварительными выпусками, часто с очень новым оборудованием, и довольно часто вижу ошибки, связанные с оптимизацией. Поскольку эти языки имеют понятия неопределенного поведения и не определяют обработку несоответствующих программ, нужно довольно тщательно проверять сбои, в конце концов, в отношении сборки. В 80-90% случаев код приложения неправильный, а не компилятор.
Фил Миллер
14

Компиляторы имеют несколько свойств, которые приводят к их корректности:

  • Домен очень хорошо известен и исследован. Проблема хорошо определена, и предлагаемые решения хорошо определены.
  • Для проверки правильности работы компиляторов достаточно автоматического тестирования
  • Компиляторы имеют очень обширные, обычно общедоступные, автоматические и модульные тесты, которые накапливались с течением времени, чтобы покрыть больше места для ошибок, чем для большинства других программ.
  • У компиляторов очень большое количество глазных яблок, следящих за их результатами
blueberryfields
источник
2
Также во многих случаях код устарел, GCC уже более 20 лет, как и многие другие, поэтому многие ошибки были устранены за длительный период времени.
Захари К
13

Мы используем компиляторы ежедневно

... и как они делают компиляторы такими надежными?

Они не Мы делаем. Поскольку все используют их постоянно, ошибки обнаруживаются быстро.

Это игра чисел. Поскольку компиляторы используются повсеместно, весьма вероятно, что любая ошибка будет вызвана кем-то, но из-за такого большого количества пользователей весьма маловероятно , что кто-то будет именно вами.

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

Конечно, помимо этого, вы можете добавить все остальные ответы здесь: компиляторы хорошо изучены, хорошо поняты. Существует миф о том, что их трудно писать, а это означает, что только очень умные, очень хорошие программисты на самом деле пытаются его написать, и при этом они особенно осторожны. Как правило, их легко тестировать, а также стресс-тест или фазз-тест. Пользователи компиляторов, как правило, сами являются опытными программистами, что приводит к высококачественным сообщениям об ошибках. И наоборот: авторы компиляторов, как правило, являются пользователями своего собственного компилятора.

Йорг Миттаг
источник
11

В дополнение ко всем ответам, я хотел бы добавить:

Я верю , что продавцы часто едят свою собачью еду. Это означает, что они пишут компиляторы сами по себе.

DevSolo
источник
7

Я часто сталкиваюсь с ошибками компилятора.

Вы можете найти их в темных углах, где меньше тестеров. Например, чтобы найти ошибки в GCC, вы должны попробовать:

  • Сборка кросс-компилятора. Вы найдете буквально десятки ошибок в скриптах GCC для настройки и сборки. Некоторые приводят к сбоям сборки во время компиляции GCC, а другие приводят к отказу кросс-компилятора создавать рабочие исполняемые файлы.
  • Создайте версию GCC для Itanium, используя profile-bootstrap. Последние пару раз я пробовал это на GCC 4.4 и 4.5, он не смог создать работающий обработчик исключений C ++. Неоптимизированная сборка работала нормально. Кажется, никто не заинтересован в исправлении ошибки, о которой я сообщил, и я сам перестал ее исправлять, пытаясь разобраться в том, что нарушало спецификации памяти GCC asm.
  • Попробуйте собрать свой собственный рабочий GCJ из последних материалов, не следуя сценарию сборки дистрибутива. Попробуй.
Зан Рысь
источник
Мы находим много проблем с IA64 (Itanium). У нас не так много клиентов для этой платформы, поэтому снижение уровня оптимизации является нашим обычным исправлением. Это возвращает нас к другим ответам: компиляторы для популярных языков для популярных архитектур обычно имели достаточную поддержку пользователей и достаточную поддержку, чтобы быть довольно хорошими, но когда вы переходите к менее популярным архитектурам и / или языкам, следует ожидать, что надежность пострадает.
Омега Центавра
@ Омега: Сокращение оптимизации, кажется, то, что все делают. К сожалению, для правильной работы Itanium требуются высокооптимизирующие компиляторы. Ну да ладно ...
Зан Рысь
Я слышу тебя. Честно говоря, архитектура уже устарела, когда она вышла, к счастью, AMD заставила Intel использовать x86-64 (что, несмотря на ее многочисленные проблемы, не так уж и плохо). Если вы можете разбить ваши исходные файлы, вы могли бы быть в состоянии изолировать, если проблема (ы) и найти обходной путь. Вот что мы делаем, если это важная платформа, но для IA64 нет.
Омега Центавра
@ Омега: К сожалению, мне действительно очень нравится Itanium. Это прекрасная архитектура. Я считаю x86 и x86-64 устаревшими, но, конечно, они никогда не умрут.
Zan Lynx
X86 немного странный Они продолжают добавлять новые вещи к этому, таким образом, это выращивает одну бородавку за один раз. Но механизм выполнения не по порядку работает довольно хорошо, а новый SSE => AVX предоставляет некоторые реальные возможности для тех, кто хочет его кодировать. По общему признанию, есть много транзисторов, предназначенных для создания устаревших вещей, но это цена, которую платят за унаследованную совместимость.
Омега Центавра
5

Некоторые причины:

  • Авторы компилятора " едят свою собачью еду ".
  • Компиляторы основаны на хорошо понятных принципах CS.
  • Компиляторы построены по очень четкой спецификации .
  • Компиляторы проходят проверку .
  • Компиляторы не всегда очень надежны .
Kramii Восстановить Монику
источник
4

Они обычно очень хороши в -O0. Фактически, если мы подозреваем ошибку компилятора, мы сравниваем -O0 с тем уровнем, который мы пытаемся использовать. Более высокие уровни оптимизации идут с большим риском. Некоторые даже намеренно так и обозначены как таковые в документации. Я встречал очень много (по крайней мере, сотню в мое время), но в последнее время они становятся все более редкими. Тем не менее, в погоне за хорошими показателями (или другими важными для маркетинга ориентирами) соблазн раздвинуть границы велик. У нас были проблемы несколько лет назад, когда вендор (чтобы остаться неназванным) решил сделать нарушение скобок по умолчанию - больше, чем какой-то особый явно помеченный параметр компиляции.

Может быть трудно диагностировать ошибку компилятора по сравнению, скажем, с ошибочной ссылкой на память, перекомпиляция с различными опциями может просто зашифровать относительное расположение объектов данных в памяти, поэтому вы не знаете, является ли это исходным кодом Heisenbug или ошибкой компилятор. Также многие оптимизации вносят законные изменения в порядок операций или даже алгебраические упрощения в вашей алгебре, и они будут иметь различные свойства в отношении округления с плавающей запятой и недостаточного / переполнения. Трудно отделить эти эффекты от РЕАЛЬНЫХ ошибок. По этой причине жесткие вычисления с плавающей запятой сложны, потому что ошибки и численная чувствительность часто нелегко распутать.

Омега Центавра
источник
4

Ошибки компилятора не так уж редки. Наиболее распространенным случаем является то, что компилятор сообщает об ошибке в коде, который должен быть принят, или для компилятора, чтобы принять код, который должен был быть отклонен.

Кевин Клайн
источник
К сожалению, мы не можем видеть второй класс ошибок: код компилируется = все хорошо. Так что, вероятно, половина ошибок (при условии, что соотношение между двумя классами ошибок составляет 50-50) не найдена людьми, а с помощью модульных тестов компилятора
Джанлука Геттини
3

Да, я столкнулся с ошибкой в ​​компиляторе ASP.NET только вчера:

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

ViewUserControl<System.Tuple<type1, type2, type3, type4, type5>>

Не будет компилироваться как есть, но будет, если type5удаляется.

ViewUserControl<System.Tuple<MyModel, System.Func<type1, type2, type3, type4>>>

Скомпилирует, если type4будет удален.

Обратите внимание, что он System.Tupleимеет много перегрузок и может принимать до 16 параметров (я знаю, это безумие).

user8685
источник
3

Вы когда-нибудь сталкивались с ошибкой в ​​самом компиляторе? Что это было и как вы поняли, что проблема была в самом компиляторе?

Ага!

Два самых запоминающихся были первые два, с которыми я столкнулся. Они оба были в компиляторе Lightspeed C для компьютеров Mac 680x0 примерно в 1985-7 годах.

Первый случай, когда при некоторых обстоятельствах целочисленный постинкрементный оператор ничего не делал - другими словами, в определенном фрагменте кода «i ++» просто ничего не делал с «i». Я вырывал свои волосы, пока не посмотрел на разборку. Затем я просто сделал инкремент и отправил отчет об ошибке.

Второй был немного сложнее, и это была действительно непродуманная «фишка», которая пошла наперекосяк. Ранние Mac имели сложную систему для выполнения операций с дисками низкого уровня. По какой-то причине я никогда не понимал - вероятно, из-за создания меньших исполняемых файлов - вместо того, чтобы компилятор просто генерировал инструкции по работе с диском на месте в объектном коде, компилятор Lightspeed будет вызывать внутреннюю функцию, которая во время выполнения генерировала операцию на диске Инструкция по стеку и там прыгнул.

Это прекрасно работает на 68000 процессорах, но когда вы запускаете один и тот же код на 68020 процессорах, это часто приводит к странным вещам. Оказалось, что новой особенностью 68020 стал кэш инструкций 256-байтовых примитивов. Начиная с первых дней работы с кешами ЦП, он не имел представления о том, что кэш «грязный» и нуждается в пополнении; Я думаю, что разработчики процессоров в Motorola не думали о самом изменяющемся коде. Таким образом, если вы выполнили две дисковые операции достаточно близко друг к другу в своей последовательности выполнения, и среда выполнения Lightspeed создала фактические инструкции в одном и том же месте в стеке, ЦП ошибочно подумал бы, что получил удар по кэшу инструкций, и дважды выполнил первую операцию на диске.

Опять же, чтобы понять это, нужно было покопаться с дизассемблером и немало пошаговых действий в отладчике низкого уровня. Мой обходной путь состоял в том, чтобы поставить перед каждой дисковой операцией префикс с вызовом функции, которая выполняла 256 «NOP» инструкций, которые заполняли (и таким образом очищали) кэш инструкций.

За 25 лет с тех пор я видел все меньше и больше ошибок компилятора. Я думаю, что есть несколько причин для этого:

  • Существует постоянно растущий набор проверочных тестов для компиляторов.
  • Современные компиляторы обычно делятся на две или более частей, одна из которых генерирует независимый от платформы код (например, нацеливание LLVM на то, что вы могли бы считать воображаемым ЦП), а другая - переводит это в инструкции для вашего фактического целевого оборудования. В многоплатформенных компиляторах первая часть используется повсеместно, поэтому она получает массу реальных испытаний.
Боб Мерфи
источник
Одна из причин, чтобы избежать самоизменения кода.
Технофил
3

Нашел явную ошибку в Turbo Pascal 5,5 лет назад. Ошибка присутствует ни в предыдущей (5.0), ни в следующей (6.0) версии компилятора. И тот, который должен был быть легко протестирован, так как он вообще не был угловым (просто вызов, который не так часто используется).

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

jwenting
источник
2

Когда поведение вашего программного обеспечения отличается при компиляции с -O0 и с -O2, вы обнаружили ошибку компилятора.

Когда поведение вашего программного обеспечения отличается от ожидаемого, есть вероятность, что ошибка в вашем коде.

mouviciel
источник
8
Не обязательно. В C и C ++ есть раздражающее количество неопределенного и неопределенного поведения, которое может на законных основаниях варьироваться в зависимости от уровня оптимизации или фазы луны или движения индексов Доу-Джонса. Этот тест работает на более четко определенных языках.
Дэвид Торнли
2

Ошибки компиляции случаются, но вы склонны находить их в нечетных углах ...

В 1990-х годах в компиляторе VAX VMS C компании Digital Equipment была странная ошибка

(Я был одет в лук на поясе, как это было в то время)

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

f(){...}
;
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++){
     puts("hello");
  }
}

В рассматриваемом компиляторе цикл выполняется только один раз.

это видит

f(){...}
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++) ;  /* empty statement for fun */

  {
     puts("hello");
  }
}

Это стоило мне много времени.

Старая версия компилятора PIC C, которую мы (раньше) применяли к опыту работы, не могла генерировать код, который правильно использовал прерывание с высоким приоритетом. Вам пришлось ждать 2-3 года и обновляться.

В компиляторе MSVC 6 была изящная ошибка в компоновщике, это могло привести к ошибке сегментации и время от времени умирать без причины. Чистая сборка вообще исправляла это (но вздыхает не всегда).

Тим Виллискрофт
источник
2

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

Аксель
источник
1

Я видел несколько ошибок компилятора, сообщал о нескольких сам (в частности, в F #).

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

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

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

Рей Миясака
источник
1

Я нашел ошибку в C # компилятор не так давно, вы можете увидеть , как Эрик Липперт (который находится на C # проектной группы) выяснили , что ошибка была здесь .

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

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

Алекс тен Бринк
источник