bug_ref_fn
Различия
Показаны различия между двумя версиями страницы.
| Следующая версия | Предыдущая версия | ||
| bug_ref_fn [2025/12/14 03:26] – создано snegovick | bug_ref_fn [2025/12/15 11:29] (текущий) – [Workaround] snegovick | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| - | Эта страница посвящена поиску бага связанного с вызовом функции init в произвольном модуле из модуля, | + | Эта страница посвящена поиску бага связанного с вызовом функции init в произвольном модуле из другого |
| + | [[https:// | ||
| + | ====== Описание ====== | ||
| + | |||
| + | В коде приведённом ниже есть есть функции empty и init. В init производится попытка вызова функции init из модуля echo (как это происходит в шелле). В случае если раскоментирован блок | ||
| + | < | ||
| + | #fp:= empty; | ||
| + | </ | ||
| + | |||
| + | или любой из if (0) включен, | ||
| + | < | ||
| + | link typecheck Echo-> | ||
| + | echo: link typecheck Echo-> | ||
| + | </ | ||
| + | |||
| + | Очевидно, | ||
| + | |||
| + | < | ||
| + | implement Sh93; | ||
| + | |||
| + | include " | ||
| + | sys: Sys; | ||
| + | |||
| + | include " | ||
| + | |||
| + | Sh93: module | ||
| + | { | ||
| + | init: fn(ctxt: ref Draw-> | ||
| + | }; | ||
| + | |||
| + | SomeT: adt { | ||
| + | f: ref fn(); | ||
| + | }; | ||
| + | |||
| + | empty() { | ||
| + | sys-> | ||
| + | } | ||
| + | |||
| + | init(ctxt: ref Draw-> | ||
| + | { | ||
| + | sys = load Sys Sys-> | ||
| + | |||
| + | #fp:= empty; | ||
| + | |||
| + | if (0) | ||
| + | { | ||
| + | st:= ref SomeT; | ||
| + | st.f = empty; | ||
| + | st.f(); | ||
| + | } | ||
| + | |||
| + | file := " | ||
| + | |||
| + | args : list of string; | ||
| + | args = " | ||
| + | args = " | ||
| + | | ||
| + | c := load Sh93 file; | ||
| + | if(c == nil) { | ||
| + | err := sys-> | ||
| + | if(err != " | ||
| + | c = load Sh93 "/ | ||
| + | if(c == nil) { | ||
| + | err = sys-> | ||
| + | } | ||
| + | } | ||
| + | if(c == nil) { | ||
| + | sys-> | ||
| + | return; | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | c-> | ||
| + | |||
| + | if (0) | ||
| + | { | ||
| + | st:= ref SomeT; | ||
| + | st.f = empty; | ||
| + | st.f(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ====== Workaround ====== | ||
| + | |||
| + | Добавление проблемной функции в объявление модуля помогает решить проблему: | ||
| + | |||
| + | < | ||
| + | Sh93: module | ||
| + | { | ||
| + | init: fn(ctxt: ref Draw-> | ||
| + | empty: fn(); | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | Lets check libinterp/ | ||
| + | [ for(l = m->ext; l->name; l++)](https:// | ||
| + | iterates over init and empty. | ||
| + | |||
| + | When you add empty to module definition explicitly, then this loop only makes single iteration with init. | ||
| + | |||
| + | Limbo does not have anonymous functions (lambdas) as far as I know, so this issue just leads to inconvenience of declaration of functions you normally would prefer not to declare. | ||
bug_ref_fn.1765682798.txt.gz · Последнее изменение: — snegovick
