Inform - Support - Patches

About Patches  


DM4 Errata  

Issue C62110

Putting an object in itself loops indefinitely
Submitted by: Eric Schmidt     Appeared in: Compiler 6.21 or before     Fixed in: Compiler 6.30

Strict mode has a function to check if the programmer is trying to move something to one of its children, which often crashes the interpreter. Instead an error message is printed. But it goes incredibly wrong when you try to put something in itself. It correctly informs you that this makes a loop. But it assumes that the object repeats itself after more than one generation: with something in-between, "house in toolbox in house." If you are directly putting something in itself, it doesn't stop after "house in house" (or whatever the object is) and keeps recursing up the object tree. Output will look similar to

  [** Programming error: tried to "move" tasty food to
  tasty food, which would make a loop: tasty food in
  tasty food in yourself in At End Of Road in nothing
  in nothing in nothing in nothing in nothing ...

And so the message, ironically, falls into an infinite loop repeating "in nothing." You can only terminate the loop using extreme measures like CTRL-ALT-DEL.

Solution (by Brendan Barnwell)

The bug is actually in the compiler's veneer. It can be fixed without modifying the compiler, though, by replacing the veneer routine RT__Err (two underscores there). The majority of this routine's code can be copied from veneer.c . The culprit is this bit:

   "16,17,18: print \"move~ \", (name) obj, \" to \", (name) id;\
   if (crime==18) { print \", which would make a loop: \",(name) obj;\
   p=id; do { print \" in \", (name) p; p=parent(p);} until (p==obj);\
   \" in \", (name) p, \" **]\"; }

(Those backslashes are not part of the actual code, they are escaping the quotes, because this entire code block is given as quoted text in veneer.c .)

In the new version of RT__Err, this portion of the switch statement should be changed to:

  print "move~ ", (name) obj, " to ", (name) id";
  if (crime==18) {
      if (obj==id) ", which would create a loop: object inside itself. **]";
      print ", which would create a loop: ";
      do {
          print " in ", (name) p;
          }  until (p==obj);
      " in ", (name) p, " **]";

Last updated 17 April 2013. This web site has not been fully supported since April 2008. Information may be out of date. This page was originally managed by Roger Firth.