OberonCore https://forum.oberoncore.ru/ |
|
Передача строк как IN-параметра? https://forum.oberoncore.ru/viewtopic.php?f=29&t=6218 |
Страница 1 из 1 |
Автор: | Vadim_Z [ Воскресенье, 21 Январь, 2018 19:01 ] |
Заголовок сообщения: | Передача строк как IN-параметра? |
Я только начал осваивать 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). В чем отличие и как лучше писать? |
Автор: | prospero78 [ Воскресенье, 21 Январь, 2018 19:17 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
IN параметр -- только для входа, т.е. изменять его нельзя. По сути, процедура работает с константой. VAR параметр -- работает с переменной, я думаю это объясняет разницу в машинном коде -- компилятор готовит структуры как для массива. 6 литер -- это 12 байт, плюс скрытые поля: тип, размер, наследование и всякое такое. OUT -- для выходных значений, длина которых может быть существенна и пихать их в стек -- накладно. По большому счёту -- OUT после недавних измений семантики -- примерно равен VAR. Уверен, что вести себя компилятор будет как и при VAR. Отсутствие префикса параметра заставляет компилчтор генерить код "по значению", а не "по ссылке". На сколько я понимаю КП. |
Автор: | Vadim_Z [ Воскресенье, 21 Январь, 2018 20:05 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
prospero78 писал(а): IN параметр -- только для входа, т.е. изменять его нельзя. По сути, процедура работает с константой. VAR параметр -- работает с переменной, я думаю это объясняет разницу в машинном коде -- компилятор готовит структуры как для массива. 6 литер -- это 12 байт, плюс скрытые поля: тип, размер, наследование и всякое такое. С VAR не компилируется (как и должно быть). С IN компилируется (кажется, это противоречит Сообщению), при этом работа в P1 действительно идет как с массивом -- я сейчас глянул ассемблерный код. Без префикса/"По значению" -- компилятор добавляет в процедуру P1 код для копирования, поэтому и размер кода больше. Самое интересное, что код процедуры Do вовсе не меняется при добавлении/удалении IN. В чем всё-таки основное отличие передачи массивов через IN и по значению, если оно есть? prospero78 писал(а): По большому счёту -- OUT после недавних измений семантики -- примерно равен VAR. Уверен, что вести себя компилятор будет как и при VAR. Поясните, пожалуйста, про какие изменения семантики речь? |
Автор: | Trurl [ Воскресенье, 21 Январь, 2018 20:18 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
Vadim_Z писал(а): Синим выделен фактический параметр, который не является (составным) именем переменной и к тому же имеет несовместимый тип (раздел Parameter compatible приложения А Сообщения). Строки в Сообщении описаны небрежно. Трудно сказать, чем же фактический параметр является. Можно считать, что именем временной переменной. |
Автор: | Vadim_Z [ Воскресенье, 21 Январь, 2018 20:20 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
Чтобы не быть голословным, вот выдача дизассемблера. Без 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, ее вызова и копирования во втором случае. |
Автор: | Trurl [ Воскресенье, 21 Январь, 2018 20:22 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
Vadim_Z писал(а): В чем всё-таки основное отличие передачи массивов через IN и по значению, если оно есть? При передаче массива по значению, его можно изменять внутри процедуры. Соответственно, будет создана копия, чтобы фактический параметр остался цел. |
Автор: | Vadim_Z [ Воскресенье, 21 Январь, 2018 20:29 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
Trurl писал(а): При передаче массива по значению, его можно изменять внутри процедуры. Соответственно, будет создана копия, чтобы фактический параметр остался цел. Trurl писал(а): Строки в Сообщении описаны небрежно. Трудно сказать, чем же фактический параметр является. Можно считать, что именем временной переменной. Спасибо, так понятнее. |
Автор: | prospero78 [ Воскресенье, 21 Январь, 2018 21:57 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
Цитата: Поясните, пожалуйста, про какие изменения семантики речь? Изменения в поведении компилятора как раз VAR/IN/OUT, также изменения коснулись процедур помеченных на экспорт для исполнения через "-" и "*". Для меня это было довольно неожиданно, часть старого кода перестала работать. Строго говоря, это было изменение языка. В каком-то смысле он стал более однозначен. Например, существует свободная доступная библиотека случайных чисел с самыми разными требованиями. Она перестала нормально компилироваться. Есть также в составе ББ пример ObxRandom -- имейте в виду, что это даже близко не тянет на случайные числа. Соответствующую библиотеку можно найти на сайте Хельмута Цинна. (* придётся ослабить требования в параметрах в тех процедурах, об которые теперь спотыкается компилятор, это совсем не сложно *) |
Автор: | Vadim_Z [ Воскресенье, 21 Январь, 2018 23:54 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
prospero78 писал(а): Изменения в поведении компилятора как раз VAR/IN/OUT, также изменения коснулись процедур помеченных на экспорт для исполнения через "-" и "*". Я нашел только вот это. Куда еще можно посмотреть? |
Автор: | prospero78 [ Понедельник, 22 Январь, 2018 11:58 ] |
Заголовок сообщения: | Re: Передача строк как IN-параметра? |
Я вообще без понятия, что там не так и почему. Меня всё устраивало)) |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |