LINUX.ORG.RU

История изменений

Исправление Legioner, (текущая версия) :

Runnable c1;
public void g(Runnable c) {
  c1 = c;
}
Runnable tmp1 = () -> {
  ....
  // 100500 строк кода
  ....
  if(cond1)
    c1.run(); // внезапно 100500 строк кода выполнились заново
  ...
  // ещё код
  ...
  if(cond2)
    c1.run(); // и снова выполнились 100500 строк кода
};
g(tmp1); // callcc(g);
tmp1();

т.е. весь кусок кода после callcc заключается в замыкание. callcc вызывается с указателем на это замыкание и потом оно само вызывается.

Исправление Legioner, :

Runnable c1;
public void g(Runnable c) {
  c1 = c;
}
Runnable tmp1 = () -> {
  ....
  // 100500 строк кода
  ....
  if(cond1)
    c1.run(); // внезапно 100500 строк кода выполнились заново
  ...
  // ещё код
  ...
  if(cond2)
    c1.run(); // и снова выполнились 100500 строк кода
};
g(tmp1); // callcc(g);
tmp1();

Исходная версия Legioner, :

Runnable c1;
public void g(Runnable c) {
  c1 = c;
}
Runnable tmp1;
tmp1 = () -> {
  ....
  // 100500 строк кода
  ....
  if(cond1)
    c1.run(); // внезапно 100500 строк кода выполнились заново
  ...
  // ещё код
  ...
  if(cond2)
    c1.run(); // и снова выполнились 100500 строк кода
};
g(tmp1); // callcc(g);
tmp1();