|
|
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
Доброго времени суток. Есть минимальный пример для воспроизведения, в нем процедура вызывает другую процедуру по переданному адресу, которая меняет var-параметр: Код Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. При компиляции 32-х битным компилятором (Delphi 2007 и Delphi XE8) без ошибок выполняется как вариант 1, так и вариант 2. При компиляции 64-х битным компилятором (Delphi XE8) без ошибок выполняется только вариант 1. Вариант 2 выдает ошибку: Ошибка--------------------------- Debugger Exception Notification --------------------------- Project Bug64.exe raised exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'. --------------------------- Break Continue Help --------------------------- Есть предположение, что проблема в том, что InnerProc вложена в метод класса , т.е. всегда имеет неявный аргумент Self. Однако, тогда не понятно, почему при компиляции в 32 бита ошибки нет. Возможно, что при компиляции в 32 бита "везет" на расположение аргументов (в регистре или на стеке), а в 64 - "не везет". Пробовал добавлять ко всем процедурам stdcall - тот же результат. Подскажите, пожалуйста, что происходит на самом деле. Без использования адреса Насколько я понимаю, вызов с использованием адреса ("CallProc(@...") приводит к "обману" проверки типов компилятора, а вызов без @ приведет к ошибкам компиляции, т.е. дельфи старается не дать программисту отстрелить себе ногу: dcc Error[dcc32 Error] uBug64.pas(52): E2094 Local procedure/function 'InnerProc' assigned to procedure variable и [dcc64 Error] uBug64.pas(52): E2094 Local procedure/function 'InnerProc' assigned to procedure variable P.S. Проблема не выдумана, такой прием активно используется в одном стороннем компоненте. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 21:39 |
|
||
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
Всё так, имеет Self - это стек, регистр rbp. Чтобы можно было SuperValue достать в Button1Click и вообще контекст не терять, как-то так выйдет: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 22:15 |
|
||
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 23:12 |
|
||
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
Нельзя так делать... На х32 вам просто везет.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 23:13 |
|
||
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
Вместо этого используйте замыкания... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 23:14 |
|
||
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
nicholaos, волшебное везение 32-х битного CallProc(@InnerProc, Value); не используйте этот знак если нет чёткого понимания зачем это нужно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2017, 00:11 |
|
||
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
Используя @, ты получаешь нетипизированный указатель, что отключает проверки компилятора. Убери @ - и компилятор сам скажет, что так делать нельзя . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2017, 02:28 |
|
||
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2017, 03:36 |
|
||
|
Локальные процедуры. Баг 64-х битного компилятора или волшебное везение 32-х битного?
|
|||
|---|---|---|---|
|
#18+
Использование замыканий, судя по всему, и проще, и правильней. Поменял объявление типов для процедур-коллбэков на "reference to procedure" - это позволило выловить все ошибки по время компиляции. Исправил все ошибки - все заработало. Всем спасибо за ответы! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2017, 15:23 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39578107&tid=2041390]: |
0ms |
get settings: |
9ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
205ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
49ms |
get tp. blocked users: |
1ms |
| others: | 234ms |
| total: | 534ms |

| 0 / 0 |
