spamsink: (Default)
[personal profile] spamsink
Короче, был такой программист по имени Эдсгер Дейкстра, который вместе с коллегой реально написал за первую половину 1960 года первый в мире компилятор с Алгола-60, по слухам, не имевший ошибок. Но не на таких напал, как мы с [personal profile] vak.

В Алголе-60 были встроенные в язык элементарные функции, типа abs, sin, cos, exp, ln и пр., которые компилировались особым образом - грубо говоря, примерно как операция изменения знака числа, которая одно число на входе имеет, и одно число на выходе выдаёт, разве что машинных команд для вычисления результата нужно больше.

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

Формально в качестве функции, передаваемой в качестве аргумента, должна быть допустима любая - как определенная программистом в программе, так и элементарная, встроенная в язык. Но из-за того, что способ вызова элементарных функций и функций, определенных в программе, был принципиально разным, большинство авторов компиляторов этим делом не заморачивались, и попросту не позволяли передавать элементарные функции как параметры, и если написано, например, слово sin, то после него обязательно должна быть открывающая скобка, иначе ошибка. А если надо вычислить интеграл от синуса, то изволь писать не
ВычислиИнтеграл(sin, начало, конец, шаг);
а сначала что-то типа
_real _function SIN(x); _real x; SIN := sin(x);
и только потом
ВычислиИнтеграл(SIN, начало, конец, шаг);

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

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

Возможно, факт наличия этой ошибки был известен, но это вряд ли, потому что будучи замечена, исправляется она элементарно: достаточно сразу после генерации кода обёртки устанавливать в переменную какое-нибудь значение, чтобы проверка упомянутой переменной на соответствие встроенной функции больше не возвращала успех.
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

spamsink: (Default)
spamsink

May 2025

S M T W T F S
     123
4 567 8910
11121314151617
18 19 2021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 22nd, 2025 05:29 am
Powered by Dreamwidth Studios
OSZAR »