Форум: "Потрепаться";
Текущий архив: 2003.09.15;
Скачать: [xml.tar.bz2];
ВнизРаз в жизни бывает... Найти похожие ветки
← →
Mystic (2003-08-25 12:26) [0]Читаю "Языки программирования (разработка и реализация)":
Правило, касающееся употребления конструкции forward в Pascal, приводит к странной аномалии, которая проиллюстрирована в программе anomaly:
program anomaly;
procedure S; {1}
begin
WriteLn("Wrong one");
end;
procedure T;
{ Здесь пропущено: procedure S; forward; } procedure U;
begin
S; {2}
end;
procedure S; {3}
begin
WriteLn("Right one");
end;
begin
U;
end;
begin
T;
end.
Читаю и думаю: чисто теоретический случай... Чтобы такое случилось когда на практике... надо постараться... И надо же такому случиться, что на следующий же день подобный глюк исправляю в своей программе пол дня. :)
← →
Е-Моё имя (2003-08-25 12:29) [1]мне не кажется это странной аномалией
← →
Palladin (2003-08-25 12:30) [2]круто завернул...
← →
Skier (2003-08-25 12:31) [3]>Mystic © (25.08.03 12:26)
> Читаю "Языки программирования (разработка и реализация)":
Пратт и Зелковиц ? :))
← →
Mystic (2003-08-25 12:35) [4]> мне не кажется это странной аномалией
Если верить спецификации Pascal, то указанный код должен привести к ошибке времени компиляции.
← →
Mystic (2003-08-25 12:36) [5]> Skier © (25.08.03 12:31) [3]
Ага, стр. 396
← →
Camus (2003-08-25 12:40) [6]А в чем же аномалия?
Что написано - то и выполняется, никаких аномалий.
← →
Camus (2003-08-25 12:43) [7]> Mystic © (25.08.03 12:35) [4]
> Если верить спецификации Pascal, то указанный код должен
> привести к ошибке времени компиляции.
Так ведь нет здесь никакой ошибки, почему компилятор должен ругаться? Ну, в лучшем случае выдаст хинт, что S {3} нигде не используется.
← →
Mystic (2003-08-25 12:52) [8]Возможно три интерпретации:
1) Ошибка компиляции (правильно, поскольку S{2} является по спецификации вызовом S{3}, но отсутсвие опережающего обяъявления должно привести к ошибке)
2) Вызов S{3} логично, но требует несколько проходов
3) Вызов S{1} продиктовано однопроходностью компилятора. Проще всего в реализации, но противоречит стандарту.
Ну тут то все понятно, я же решил еще помучить свою любимый менеджер памяти Delphi и сделал то, что давно было надо. Написал
unit MyMemMgr;
interface
implementation
const
kernel = "kernel32.dll";
{$I GetMem.inc}
var
MyMemMgr: TMemoryManager =
(
GetMem: SysGetMem;
FreeMem: SysFreeMem;
ReallocMem: SysReallocMem;
);
initialization
SetMemoryManager(MyMemMgr);
end.
и долго искал ошибку... Строчка
function SysFreeMem(P: Pointer): Integer;
перед {$I GetMem.inc} спасла отца русской демократии...
← →
Camus (2003-08-25 13:22) [9]> Mystic © (25.08.03 12:52) [8]
Почему? Как раз если исходить из принятых в стандартном Паскале правил (а они должны быть отражены и в формальной грамматике языка), то S{2} является совершенно нормальным вызовом S{1} и ничему не противоречит.
Странно как-то. Сомневаться в компетентности авторов ТАКОЙ книги, конечно, не приходится, но все же что-то тут не так.
Нет ли ссылки на спецификацию стандарта языка? Самому найти не удалось - поисковики выдают кучу ссылок, но все не то.
← →
Anatoly Podgoretsky (2003-08-25 13:31) [10]Аномалия будет если вместо S1 будет вызван S3, а у тебя что вызывается?
← →
DiamondShark (2003-08-25 13:55) [11]
> Mystic © (25.08.03 12:52) [8]
> Возможно три интерпретации:
> 1) Ошибка компиляции (правильно, поскольку S{2} является
> по спецификации вызовом S{3}, но отсутсвие опережающего
> обяъявления должно привести к ошибке)
> 2) Вызов S{3} логично, но требует несколько проходов
> 3) Вызов S{1} продиктовано однопроходностью компилятора.
> Проще всего в реализации, но противоречит стандарту.
Неверно.
1) С чего это вдруг? В точке вызова S {2} у компилятора имеется описание S {1}, которое подходит по сигнатуре.
2) Не логично и не требует
3) Не противоречит. Всё согласно соглашениям об области видимости и поряде описания.
← →
Mystic (2003-08-25 15:31) [12]> С чего это вдруг?
Раздел 6.2.2.1 стандарта языка Паскаль
← →
Mystic (2003-08-25 16:11) [13]Вот порылся в стандарте паскаля и нашел:
6.2.2.1 Each identifier or label contained by the program-block have a definition point
6.2.2.2 Each definition point shell have a region that is a part of the program text, and a scope that is a part or all of that region.
6.2.2.3 The region of each definig-point is defined elsewhere (see 6.2.1, 6.2.2.10, 6.3, 6.4.1, 6.4.2.3, 6.4.3.3, 6.5.1, 6.5.3.3, 6.6.1, 6.6.2, 6.8.3.10, 6.10)
6.6.1 <...> The occurrence of an identifier in the procedure of a procedure-declaration shell constitude its defining-point as a procedure-identifier for the region that is the block closest-containing the procedure-declaration.
И
6.2.2.9 The defining-point of an identifier or label shall precede all occurrences of that identifier or label contained by the program block with one exception, namely that an identifier can have an applied occurrence in the type-identifier of the domain-type of any new-pointer-types conteined by the type-definition-part containing the defining-point of the type-identifier.
← →
DiamondShark (2003-08-25 18:07) [14]Ну и в чём непонятка? Картинки что-ли рисовать? Можно.
http://moldovacc.md/acoulichev/anomaly.gif
← →
Mystic (2003-08-25 19:30) [15]Да нет, по определению region процедуры (6.6.1) это closest-containing блок, в котором она определена. Т. е. для процедуры S таким регионом будет процедура T. Следовательно, ссылки {2} на на процедуру S из процедуры T должны рассматриваться только как вызов процедуры S{3}. С учетом правила 6.2.2.9, это приводит к ошибке.
Я это вовсе не к тому привел. Мне просто хотелось спросить, как часто описание возможной ошибки читается за день до того, как эта ошибка совершается? Или это я один такой?
← →
Camus (2003-08-25 20:43) [16]> Mystic © (25.08.03 19:30) [15]
> Да нет, по определению region процедуры (6.6.1) это closest-
> containing блок, в котором она определена. Т. е. для процедуры
> S таким регионом будет процедура T.
С маленьким уточнением - блок для S3 начинается только ПОСЛЕ ее декларации (что полностью соответствует 6.2.2.9 - " shall precede "). А ДО декларации S3 действует блок для S1.
> Следовательно, ссылки {2} на процедуру S из процедуры T
> должны рассматриваться только как вызов процедуры S{3}.
А вот это неверно. Смотря, какие ссылки. Если ДО объявления S3, то это будут ссылки на S1. Все по спецификации.
← →
uw (2003-08-26 11:38) [17]>Mystic © (25.08.03 16:11) [13]
А есть ссылка на стандарт Паскаля? Хотелось бы уяснить разницу между program-block и region.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2003.09.15;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.012 c