OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 17 Декабрь, 2018 19:40

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 19:01 

Зарегистрирован: Пятница, 19 Январь, 2018 19:27
Сообщения: 12
Я только начал осваивать BB/CP, и появились вопросы по языку. Простите, если они покажутся дурацкими.

Рассмотрим код:
MODULE TestMod1;

IMPORT StdLog;

PROCEDURE P1(IN name: ARRAY OF CHAR);
BEGIN
StdLog.Int(LEN(name)); StdLog.Ln;
END P1;

PROCEDURE Do*;
VAR x: ARRAY 10 OF CHAR;
BEGIN
P1('abc'+'def');

END Do;

END TestMod1.

Согласно п. 9.2 Сообщения о языке:
Цитата:
There are two kinds of parameters: variable and value parameters.
If a formal parameter is a variable parameter, the corresponding actual parameter must be a designator denoting a variable.


Красным в коде выше выделен формальный параметр name, он относится к виду variable parameters (п. 10.1 Сообщения). Синим выделен фактический параметр, который не является (составным) именем переменной и к тому же имеет несовместимый тип (раздел Parameter compatible приложения А Сообщения).

Тогда почему приведенный выше фрагмент вообще компилируется?

Если заменить красное IN на VAR, выдается логичная ошибка: actual VAR-, IN-, or OUT-parameter is not a variable (122).
Если вообще убрать IN (передавать по значению), код также компилируется, объектный файл имеет другой размер: с IN -- 56 байт, без IN -- 128. В дизассемблер пока не смотрел, но уже понятно, что код другой.

В то же время выдача что с IN, что без IN одинаковая.

Заодно возникает следующий вопрос: я видел в коде BB, что строки принимаются в разных случаях и по значению, и как переменные (IN). В чем отличие и как лучше писать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 19:17 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1094
Откуда: СССР v2.0 rc 1
IN параметр -- только для входа, т.е. изменять его нельзя. По сути, процедура работает с константой.
VAR параметр -- работает с переменной, я думаю это объясняет разницу в машинном коде -- компилятор готовит структуры как для массива. 6 литер -- это 12 байт, плюс скрытые поля: тип, размер, наследование и всякое такое.
OUT -- для выходных значений, длина которых может быть существенна и пихать их в стек -- накладно. По большому счёту -- OUT после недавних измений семантики -- примерно равен VAR.
Уверен, что вести себя компилятор будет как и при VAR.
Отсутствие префикса параметра заставляет компилчтор генерить код "по значению", а не "по ссылке". На сколько я понимаю КП.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 20:05 

Зарегистрирован: Пятница, 19 Январь, 2018 19:27
Сообщения: 12
prospero78 писал(а):
IN параметр -- только для входа, т.е. изменять его нельзя. По сути, процедура работает с константой.
VAR параметр -- работает с переменной, я думаю это объясняет разницу в машинном коде -- компилятор готовит структуры как для массива. 6 литер -- это 12 байт, плюс скрытые поля: тип, размер, наследование и всякое такое.


С VAR не компилируется (как и должно быть).
С IN компилируется (кажется, это противоречит Сообщению), при этом работа в P1 действительно идет как с массивом -- я сейчас глянул ассемблерный код.
Без префикса/"По значению" -- компилятор добавляет в процедуру P1 код для копирования, поэтому и размер кода больше.

Самое интересное, что код процедуры Do вовсе не меняется при добавлении/удалении IN.
В чем всё-таки основное отличие передачи массивов через IN и по значению, если оно есть?

prospero78 писал(а):
По большому счёту -- OUT после недавних измений семантики -- примерно равен VAR.
Уверен, что вести себя компилятор будет как и при VAR.


Поясните, пожалуйста, про какие изменения семантики речь?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 20:18 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1098
Vadim_Z писал(а):
Синим выделен фактический параметр, который не является (составным) именем переменной и к тому же имеет несовместимый тип (раздел Parameter compatible приложения А Сообщения).

Строки в Сообщении описаны небрежно. Трудно сказать, чем же фактический параметр является. Можно считать, что именем временной переменной.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 20:20 

Зарегистрирован: Пятница, 19 Январь, 2018 19:27
Сообщения: 12
Чтобы не быть голословным, вот выдача дизассемблера.

Без IN (по значению):
Код:
PROCEDURE $$
00000000H:   C3    ret 

PROCEDURE P1
00000001H:   55    push  ebp
00000002H:   8B EC    mov  ebp, esp
00000004H:   8B 4D 0C    mov  ecx, 12[ebp]
00000007H:   8B 75 08    mov  esi, 8[ebp]
0000000AH:   01 C9    add  ecx, ecx
0000000CH:   E8 38 00 00 00   call  56  (00000049H)
00000011H:   8B FC    mov  edi, esp
00000013H:   89 7D 08    mov  8[ebp], edi
00000016H:   F3    rep 
00000017H:   A5    movsd 
00000018H:   8B 45 0C    mov  eax, 12[ebp]
0000001BH:   99    cwd 
0000001CH:   52    push  edx
0000001DH:   50    push  eax
0000001EH:   E8 00 00 00 65   call  1694498816  (65000023H)
00000023H:   E8 00 00 00 65   call  1694498816  (65000028H)
00000028H:   8B E5    mov  esp, ebp
0000002AH:   5D    pop  ebp
0000002BH:   C2 08 00   ret  8

PROCEDURE Do
0000002EH:   55    push  ebp
0000002FH:   8B EC    mov  ebp, esp
00000031H:   57    push  edi
00000032H:   56    push  esi
00000033H:   83 C4 EC    add  esp, -20
00000036H:   6A 07    push  7
00000038H:   68 00 00 00 64   push  1677721600
0000003DH:   E8 BF FF FF FF   call  -65  (00000001H)
00000042H:   8D 65 F8    lea  esp, -8[ebp]
00000045H:   5E    pop  esi
00000046H:   5F    pop  edi
00000047H:   5D    pop  ebp
00000048H:   C3    ret 

PROCEDURE $StackAlloc
00000049H:   50    push  eax
0000004AH:   83 C1 FB    add  ecx, -5
0000004DH:   79 02   jns  2  (00000051H)
0000004FH:   31 C9    xor  ecx, ecx
00000051H:   83 E1 FC    and  ecx, FFFFFFFCH
00000054H:   8B C1    mov  eax, ecx
00000056H:   25 FF 0F 00 00    and  eax, 00000FFFH
0000005BH:   2B E0    sub  esp, eax
0000005DH:   8B C1    mov  eax, ecx
0000005FH:   C1 E8 0C    shr  eax, 12
00000062H:   74 0B   jz  11  (0000006FH)
00000064H:   6A 00    push  0
00000066H:   81 EC FC 0F 00 00    sub  esp, 4092
0000006CH:   48    dec  eax
0000006DH:   75 F5   jnz  -11  (00000064H)
0000006FH:   83 C1 08    add  ecx, 8
00000072H:   8B 44 0C FC    mov  eax, -4[esp + 1 * ecx]
00000076H:   50    push  eax
00000077H:   8B 44 0C FC    mov  eax, -4[esp + 1 * ecx]
0000007BH:   C1 E9 02    shr  ecx, 2
0000007EH:   C3    ret 


С IN:
Код:
PROCEDURE $$
00000000H:   C3    ret 

PROCEDURE P1
00000001H:   55    push  ebp
00000002H:   8B EC    mov  ebp, esp
00000004H:   8B 45 0C    mov  eax, 12[ebp]
00000007H:   99    cwd 
00000008H:   52    push  edx
00000009H:   50    push  eax
0000000AH:   E8 00 00 00 65   call  1694498816  (6500000FH)
0000000FH:   E8 00 00 00 65   call  1694498816  (65000014H)
00000014H:   8B E5    mov  esp, ebp
00000016H:   5D    pop  ebp
00000017H:   C2 08 00   ret  8

PROCEDURE Do
0000001AH:   55    push  ebp
0000001BH:   8B EC    mov  ebp, esp
0000001DH:   57    push  edi
0000001EH:   56    push  esi
0000001FH:   83 C4 EC    add  esp, -20
00000022H:   6A 07    push  7
00000024H:   68 00 00 00 64   push  1677721600
00000029H:   E8 D3 FF FF FF   call  -45  (00000001H)
0000002EH:   8D 65 F8    lea  esp, -8[ebp]
00000031H:   5E    pop  esi
00000032H:   5F    pop  edi
00000033H:   5D    pop  ebp
00000034H:   C3    ret 


Видно отсутствие $StackAlloc, ее вызова и копирования во втором случае.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 20:22 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1098
Vadim_Z писал(а):
В чем всё-таки основное отличие передачи массивов через IN и по значению, если оно есть?

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 20:29 

Зарегистрирован: Пятница, 19 Январь, 2018 19:27
Сообщения: 12
Trurl писал(а):
При передаче массива по значению, его можно изменять внутри процедуры. Соответственно, будет создана копия, чтобы фактический параметр остался цел.


Trurl писал(а):
Строки в Сообщении описаны небрежно. Трудно сказать, чем же фактический параметр является. Можно считать, что именем временной переменной.


Спасибо, так понятнее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 21:57 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1094
Откуда: СССР v2.0 rc 1
Цитата:
Поясните, пожалуйста, про какие изменения семантики речь?

Изменения в поведении компилятора как раз VAR/IN/OUT, также изменения коснулись процедур помеченных на экспорт для исполнения через "-" и "*". Для меня это было довольно неожиданно, часть старого кода перестала работать. Строго говоря, это было изменение языка. В каком-то смысле он стал более однозначен. Например, существует свободная доступная библиотека случайных чисел с самыми разными требованиями. Она перестала нормально компилироваться. Есть также в составе ББ пример ObxRandom -- имейте в виду, что это даже близко не тянет на случайные числа. Соответствующую библиотеку можно найти на сайте Хельмута Цинна. (* придётся ослабить требования в параметрах в тех процедурах, об которые теперь спотыкается компилятор, это совсем не сложно *)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Воскресенье, 21 Январь, 2018 23:54 

Зарегистрирован: Пятница, 19 Январь, 2018 19:27
Сообщения: 12
prospero78 писал(а):
Изменения в поведении компилятора как раз VAR/IN/OUT, также изменения коснулись процедур помеченных на экспорт для исполнения через "-" и "*".


Я нашел только вот это. Куда еще можно посмотреть?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Передача строк как IN-параметра?
СообщениеДобавлено: Понедельник, 22 Январь, 2018 11:58 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1094
Откуда: СССР v2.0 rc 1
Я вообще без понятия, что там не так и почему.
Меня всё устраивало))


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2018, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB