IPB
ЛогинПароль:

> Правила раздела!

1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!

> Несоответсвие типов VAR-параметров подпрограмм(error 26).
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 51
Пол: Мужской

Репутация: -  0  +


Извиняюсь за возможное нарушение правил, но решил поместить пример программы,
чтобы сразу было понятно что к чему.

ПРОГРАММА:
Код

program VarStr;

uses
   Dos;

procedure Proc( var Dir : DirStr; var Name : NameStr; var Ext : ExtStr );
begin
end;

procedure Proc2( var B : Byte; var W : Word; var L : LongInt );
begin
end;

procedure Proc3( var I : Integer; var W : Word );
begin
end;

procedure Proc21( B : Byte; W : Word; L : LongInt );
begin
end;

var
   SD, SN, SE : String;
   SDir : DirStr;
   SName : NameStr;
   SExt : ExtStr;
   B : Byte;
   W : Word;
   L : LongInt;
   I : Integer;
begin
   (*Proc(SD,SN,SE);  { НЕЛЬЗЯ! Ошибка 26: Type mismatch(несовпадение типов). }*)
   Proc(SDir,SName,SExt);  { Всё в порядке! }
   (*Proc2(B,B{Error 26!},B);*)
   (*Proc2(W{Error 26!},W,W);*)
   (*Proc2(L{Error 26!},L,L);*)
   Proc2(B,W,L);  { Всё в порядке! }
   (*Proc3(W{Error 26!},W);*)
   (*Proc3(W{Error 26!},I);*)
   (*Proc3(I,I{Error 26!});*)
   Proc3(I,W);  { Всё в порядке! }
   Proc3(Integer(W),Word(I));  { Всё в порядке! }
   Proc21(B,W,L);  { Всё в порядке! }
   Proc21(L,B,W);  { Всё в порядке! }
   Proc21(W,L,B)  { Всё в порядке! }
end.


И сам ВОПРОС(недеюсь он теоретический(имеет отношение к синтаксису, семантике и т.д. и т.п)):
Почему типы фактических параметров переменных, задаваемых при вызове подпрограммы,
должны СОВПАДАТЬ(быть РАВНЫМИ) соответствующим формальным VAR-параметрам.
Почему здесь ошибка 26(Type mismatch) - НЕСООТВЕТСТВИЕ ТИПОВ превращается в ошибку
НЕСОВПАДЕНИЕ ТИПОВ.


Пожалуйста, если кто-нибудь знает, объясните.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


code warrior
****

Группа: Пользователи
Сообщений: 484
Пол: Мужской
Реальное имя: Славен

Репутация: -  8  +


Есть такое понятие в программировании - безопасный код.
Помимо всего прочего (про exceptionы и потокобезопасность здесь речь не пойдет) оно включает в себя стиль написания программы, который не допускает работу с указателями в явной форме - получение, разыменование, арифметика на ним, также не приветствуются операции приведения типов.

Вместо указателей настоятельно рекомендуется использовать ссылки, а типы преобразовывать в явном виде - через операции присваивания, встроенные функции и т.п.

Т.е. нужно как можно больше работы сбрасывать на компилятор - статический контроль типов, управление памятью и прочую рутину. Он умеет это лучше чем человек.

Теперь по поводу совместимости и эквивалентности.

Совместимость типов - это такое отношение между двумя типами, которое доступно компилятору на этапе синтаксического анализа исходника. Т.е. компилятор ЗНАЕТ как перевести тип А в тип Б.
Например real совместим с integer (переменной типа real можно присвоить значение переменной типа integer), но не наоборот.

Эквивалентность типов - имеется в виду двоичная эквивалентность, это отношение между типами, выстроенное на основе размера памяти в байтах, который занимает переменная того или иного типа.
Например у нас есть запись вида:
Код

TMyDWord = packed record
    HiWord: Word;
    LoWord: Word;
end;

Если мы имеем переменную типа Dword то мы вполне можем привести её к типу TMyDWord. Это приведение допустимо потому что размер занимаемый TMyDword равен размеру DWord. Обратное приведение также возможно.
Эквивалентность типов может зависеть от настроек компилятора. Если мы поставим выравнивание полей записи по 4 байтам (это сильно ускорит их обработку) приведенный выше пример не будет работать, так как размеры перестанут совпадать и отношение двоичной эквивалентности между типами пропадет.

Операция приведения типа оперирует с понятием эквивалентности типов. Мы можем привести тип А к типу Б в том случае, когда size(А) >= size(Б). Это ограничение не позволит обратиться к, возможно, невыделенной области памяти, что приведет к AV-исключению.

При передаче параметров в подпрограммы или методы, для компилятора очень важен ТИП подставляемх фактических параметров, именно на основе их типов, он будет вызывать нужную перегруженную версию (если они есть) сабрутины. Отсюда правило - нужно ЗНАТЬ что ты хочешь сделать, чтобы небыло недопонимания с компилером.

Цитата
Мне кажется, что оба действия - и Type1(Type2Variable) и Type1((@Type2Variable)^) - выполняются на этапе
компиляции. Но почему в первом случае создаётся локальная копия(для VAR-параметров), по какому синтаксическому правилу?
Я уже объяснял..... Первый вариант приводит к копированию данных во временную переменную. Второй вариант компилятор рассматривает как некое переобъявление переменной. Разыменованный указатель - это переменная, операция приведения типа выступает в качестве декларирования типа переменной. Именно поэтому такая запись пригодна для передачи параметра по ссылке.


Добавлено через 6 мин.
Ваял предыдущий креатив.....
Цитата(Neznaika @ 11.08.2007 18:41) *

А можно ли вообще использовать в качестве фактических параметров процедур для VAR-параметров ВЫРАЖЕНИЯ? Для W типа Word конструкция Byte(W) - это выражение.

В принципе - можно. Если выражение своим результатом возвращает указатель, то используя технику дзен
Код

Type1((PType1PointerExpression)^)

Мы можем передавать данные по ссылке.
Другое дело, что нам потребуется написать выражение, результатом которого будет некий указаталь (с точки зрения безопасного кода подобные действия никуда не годятся).


--------------------
ИзВ ин ИтЕ зА нЕ рОв НЫй П оч ЕРк
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
Neznaika   Несоответсвие типов VAR-параметров подпрограмм(error 26).   13.07.2007 16:44
compiler   procedure p( const s:string ); begin writeLn(s); …   13.07.2007 17:25
volvo   Ничего никуда не превращается. Как всегда было Err…   13.07.2007 17:43
Neznaika   compiler: Не смешно, мой пример СИНТАКСИЧЕСКИ КОРР…   13.07.2007 20:14
volvo   Если ты не понял того, что написано в предыдущем п…   13.07.2007 20:31
Neznaika   volvo: Я не хочу ругаться, я разобраться хочу. Про…   13.07.2007 22:02
Neznaika   Вот например, что написано у Епанешниковых(Програм…   14.07.2007 19:49
compiler   Получается, что типы данных формальных и фактическ…   14.07.2007 20:05
Neznaika   тебе же написали а еще многие ошибки вообще не …   14.07.2007 20:52
volvo   Дельфи? Сорри, только не Дельфи: Что я делаю не…   14.07.2007 20:58
Neznaika   unit Unit1; interface uses Windows, Messages,…   14.07.2007 21:07
мисс_граффити   Естественно. А где в этом примере несоответствие м…   14.07.2007 23:57
volvo   Разговор был про Var-параметры... Попробуй добавит…   15.07.2007 1:07
Neznaika   Тьфу, чёрт. Теперь вроде всё "правильно…   15.07.2007 3:22
Neznaika   BDS2006(компилятор Delphi для Win32): ... var W…   18.07.2007 20:42
hardcase   Уважаемые эксперты, объясните пожалуйста 1) Что…   9.08.2007 1:16
Neznaika   hardcase, спасибо. Но всё равно, тёмное дело. В…   11.08.2007 20:36
volvo   Neznaika, во-первых, будет ли твоя программа компи…   11.08.2007 21:00
Neznaika   Да, с {$T+} Proc(Word((@B)^),DWord((@B)^)); н…   11.08.2007 21:41
hardcase   Есть такое понятие в программировании - безопасный…   11.08.2007 22:23


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 8.05.2024 15:38
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name