В дополнение ко всем отличным ответам пока:
У вас есть "предвзятость наблюдателя". Вы не видите ошибок, и поэтому вы предполагаете, что их нет.
Я привык думать, как ты. Затем я начал профессионально писать компиляторы, и позвольте мне сказать вам, что там много ошибок!
Вы не видите ошибок, потому что вы пишете код, который составляет 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 по ссылке. И если бы вы это сделали, вы, вероятно, даже не заметили бы, что третье сообщение об ошибке бессмысленно, поскольку первое является правильным и достаточным для диагностики проблемы. Но я стараюсь делать такие вещи, потому что я пытаюсь сломать компилятор. Если бы вы попробовали, вы бы тоже увидели ошибки.