Мета компілятора - створити виконувані файли, які ведуть себе за бажанням. Якщо програміст записує щось недійсне, навіть якщо компілятор може з 90% вірогідністю здогадатися, що було призначено, як правило, краще вимагати від програміста виправити програму, щоб зрозуміти намір, ніж компілятор піти вперед і створити виконуваний файл який мав би значний шанс приховати помилку.
Звичайно, мови, як правило, повинні бути розроблені так, що код, який чітко виражає намір, буде законним, а код, який не чітко виражає наміри, повинен бути заборонений, але це не означає, що вони є. Розглянемо наступний код [Java або C #]
const double oneTenth = 0.1;
const float oneTenthF = 0.1f;
...
float f1 = oneTenth;
double d1 = oneTenthF;
Якщо компілятор додати неявний typecast для призначення, це f1
було б корисно, оскільки існує лише одна логічна річ, яку може захотіти f1
містити програміст ( float
значення, найближче до 1/10). Замість того, щоб заохочувати компіляторів приймати неправильні програми, тим не менше, специфіка могла б дозволити неявні перетворення в подвійному плаванні в деяких контекстах. З іншого боку, присвоєння програмісту d1
може бути, а може, і не бути таким, як програміст насправді мав намір, але немає жодного мовного правила, яке забороняло б його.
Найгірші різновиди мовних правил - це ті, коли компілятори робитимуть умовиводи у випадках, коли щось не могло б законно скласти інакше, але коли програма може «випадково» бути дійсною у випадку, коли було призначено висновок. Багато ситуацій, пов’язаних із неявним закінченням заяви, підпадають під цю категорію. Якщо програміст, який має намір записати два окремі оператори, відмовляється від термінатора операторів, компілятор, як правило, вдається вивести межу оператора, але іноді може вважати одним твердженням щось, що повинно було оброблятися як два.