Además de todas las excelentes respuestas hasta ahora:
Tienes un "sesgo de observador". No observa errores, y por lo tanto asume que no hay ninguno.
Solía pensar como tú. Luego comencé a escribir compiladores profesionalmente, y déjame decirte que hay muchos errores allí.
No ves los errores porque escribes código que es como el 99.999% de todo el resto del código que la gente escribe. Probablemente escriba código perfectamente normal, directo y claramente correcto que llame a métodos y ejecute bucles y no haga nada elegante o extraño, porque es un desarrollador normal que resuelve problemas comerciales normales.
No ve ningún error del compilador porque los errores del compilador no se encuentran en los escenarios de código normales sencillos y fáciles de analizar; los errores están en el análisis de código extraño que no escribes.
Por otro lado, tengo el sesgo de observador opuesto. Veo códigos locos todo el día todos los días, y para mí los compiladores parecen estar llenos de errores.
Si se sentó con la especificación de idioma de cualquier idioma, y tomó cualquier implementación del compilador para ese idioma, y realmente trató de determinar si el compilador implementó exactamente la especificación o no, concentrándose en casos de esquina oscuros, muy pronto encontrará errores del compilador con bastante frecuencia. Déjame darte un ejemplo, aquí hay un error del compilador de C # que encontré literalmente hace cinco minutos.
static void N(ref int x){}
...
N(ref 123);
El compilador da tres errores.
- Un argumento ref o out debe ser una variable asignable.
- La mejor coincidencia para N (ref int x) tiene argumentos no válidos.
- Falta "ref" en el argumento 1.
Obviamente, el primer mensaje de error es correcto y el tercero es un error. El algoritmo de generación de errores está tratando de descubrir por qué el primer argumento no es válido, lo mira, ve que es una constante y no vuelve al código fuente para verificar si se marcó como "ref"; más bien, supone que nadie sería tan tonto como para marcar una constante como referencia, y decide que la referencia debe faltar.
No está claro cuál es el tercer mensaje de error correcto, pero este no lo es. De hecho, tampoco está claro si el segundo mensaje de error es correcto. ¿Debería fallar la resolución de sobrecarga o "ref 123" debería tratarse como un argumento de referencia del tipo correcto? Ahora tendré que pensarlo un poco y hablarlo con el equipo de selección para que podamos determinar cuál es el comportamiento correcto.
Nunca has visto este error porque probablemente nunca harías algo tan tonto como para intentar pasar 123 por ref. Y si lo hiciera, probablemente ni siquiera notaría que el tercer mensaje de error no tiene sentido, ya que el primero es correcto y suficiente para diagnosticar el problema. Pero trato de hacer cosas así, porque estoy tratando de romper el compilador. Si lo intentaras, también verías los errores.