Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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.49 MB
Время: 0.018 c
3-48399
rh
2003-08-26 12:39
2003.09.15
Записать текущую дату


1-48503
Bumer
2003-09-02 17:37
2003.09.15
добавить объект


1-48545
ZoKr
2003-09-02 05:32
2003.09.15
Excel Copy


8-48655
Still Swamp
2003-05-17 17:26
2003.09.15
Как прервать воспроизведение?


14-48738
Delphi5.01
2003-08-26 19:47
2003.09.15
Запасный выход





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский