Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.216.233.58] |
|
Сообщ.
#1
,
|
|
|
В дизайнере код работает - при нажатии кнопки получаем "OK" на выходе:
Private Sub Test(Flag As Boolean) Dim i As Long, sArr() As String If Flag Then ReDim sArr(0) i = 0 GoTo mNext End If ReDim sArr(0 to 9) For i = 0 To UBound(sArr) mNext: Next lblRes.Caption = "OK" End Sub Private Sub Command1_Click() Test True End Sub В exe код зависает (Win10), не срабатывает Next (происходит зацикливание). В чём причина? |
Сообщ.
#2
,
|
|
|
Цитата BlackSun @ В чём причина? У меня не на чем собрать. Покажи ассемблер этой функции, там надо разбираться |
Сообщ.
#3
,
|
|
|
Если бы я работал на уровне ассемблера, не спрашивал бы тут. Могу exe подцепить. Может, что-то не так в настройках компиляции? Может, у меня нет каких-то патчей? Может нельзя прыгать в тело цикла без отработки кода на For - ведь при прямом заходе в цикл (Test False) код работает... ?
Но читатели же могут скомпилить у себя и проверить... На разных Win также... |
Сообщ.
#4
,
|
|
|
Цитата BlackSun @ Может, что-то не так в настройках компиляции? Если скомпилировать в P-Code - будет работать. Цитата BlackSun @ Может нельзя прыгать в тело цикла Вообще-то, даже простое использование GoTo в наше время - это моветон, но такой прыжок - однозначно ошибка. И совершенно непонятно, зачем это может понадобиться. Выражение, которое находится после слова "To", вычисляется в момент срабатывания "For", при таком прыжке оно не вычислено, то есть "Next" не знает, возвращаться, или уже не надо. |
Сообщ.
#5
,
|
|
|
Цитата Mikle @ то есть "Next" не знает заменил For i = 0 To UBound(sArr) MaxIdx=UBound(sArr) ... For i = 0 To MaxIdx также не работает... Next должен компилироваться в: i=i+1 If I<=MaxIdx then goto НачалоТелаЦикла Т.е. имеем просто значение MaxIdx в памяти и всё должно работать. Но, видно, что-то не так. Добавлено Цитата Mikle @ GoTo в наше время - это моветон Почему? Добавлено Да, в P-Code работает. В Native - виснет. Добавлено Цитата Mikle @ И совершенно непонятно, зачем это может понадобиться. Тело цикла очень большое, и выносить его в процедуру - головняк. Тем более, что нужно прыгнуть где-то в середину, при выносе в процедуру надо не забыть ни одной переменной передать ей и вернуть всё правильно, также возможны прыжки в разные места тела и т.д. - лопатить старый код хлопотно, но на поиск проблемы день ушёл , никогда бы не подумал, что Next может так сработать, тело лопатил... Проще было прыгнуть в нужное место - так и написал. Добавлено Значит, дизайнер работает в P-Code при выполнении? Добавлено Цитата Mikle @ есть "Next" не знает Next всё одно должен с чем-то сравнивать I, он же не может поставить безусловный переход на начало тела в Native варианте? |
Сообщ.
#6
,
|
|
|
Цитата BlackSun @ заменил Какая разница? Пока For не выполнится, Next не знает, что там MaxIdx. Простейший пример: Private Sub Form_Click() Dim i As Long, d As Long d = 8 GoTo Label For i = 0 To d Label: Next i Caption = i End Sub На выходе получает "1". То есть один раз выполнилось "i=i+1", и далее выход по Next. Поменяй "For i = -5 To d" - всё равно на выходе "1", то есть цикл работал, но до нуля, то, что там d=8, Next не знал. Значит в IDE и P-Code переменная конца цикла равна "0" до того, как выполнился For. Но в нативном коде Next не знает даже адреса перехода в начало, цикл не зацикливается, а зависает на перехода по неизвестному (возможно, случайному) адресу после Next. |
Сообщ.
#7
,
|
|
|
т.е. получается, что значение IdxMax копируется на For в др. ячейку памяти. Далее IdxMax может меняться, но цикл возьмёт его первичное значение на For. Если эта ячейка памяти содержит 0, то в моём случае будет выход из цикла, похоже, она содержит MaxLong или же случайное значение (не записанное)!
Добавлено Цитата Mikle @ Но в нативном коде Next не знает даже адреса перехода в начало, цикл не зацикливается отладка показала бесконечный проход по циклу, возможно, был прыжок на Next в начало процедуры. Не знаю тонкостей Native-кода, но смысл проблемы ясен. Добавлено Отладка на exe через точки вывода на коде, ведь в дизайнере всё было OK. Кстати, как правильно было делать отладку в exe-варианте, не сталкивался с этим. Добавлено Цитата Mikle @ GoTo в наше время - это моветон я где-то читал, что такой код прогеры называют соплями, но меня лично раздражают проблемы с кучей вложенных If... End If - чуть где ошибся - и головняк с поиском - где не закрыл If; компилятор мог бы и сам это определить, шагая от внутреннего If к внешнему, но он не может, а ругается сразу на For...Next! |