There seems to be a weird bug in sc that I haven't been able to figure out.
I don't know if this bug is present under O/S's besides Linux, or when
compiled with compilers besides gcc, but I'd be interested in finding out.
I've implemented a work-around, but it seems to me there must be a better
way.  For anyone who would like to take this on and thinks they might be
able to figure it out, I'd be very grateful.

Here's the problem.  After I released version 7.1, I noticed that
the "Still changing after x iterations" error message was coming up
quite often when it didn't seem that it should.  Turning automatic
optimization of expressions off (e.g. starting sc with the -o switch)
seems to eliminate the problem, but I don't think the bug is directly
related to optimization (someone correct me if I'm wrong).  After a little
testing, I discovered that there were some simple calculations that would
bring up the error even if there was nothing else in the spreadsheet.
I couldn't find any pattern to what would cause the error and what
wouldn't.  For example, if you start up sc without specifying a file,
and then enter the numeric expression "1.2+2.1" in cell A0, you will
immediately see the error (this must be done in version 7.1, not 7.2,
unless you delete the workaround, but more about this later).

I looked through the source code, and decided that I needed to start my
search in interp.c for the bug.  In particular, there is an if block that
starts with the following line:

	if ((p->cellerror = cellerror) || (v != p->v)) {

You can find this block in version 7.2 by searching in interp.c for either
my initials ("CRM") or the word "BUGS", which both occur in a comment I
placed there about this bug.

I first tried to look at the values of v and p->v with dbg, and got really
weird results that made no sense to me, so I decided to insert the
following debugging code into the beginning of the block of code that is
executed if the above test is true:

	    error("v = %f; p->v = %f; chgct= %d.", v, p->v, *chgct);
	    refresh();

With this code in the block, the bug went away (it seems Heisenberg isn't
limited to the physical world).  In fact, I found out that I could place
these two lines anywhere in the block, or even outside of the block within
the enclosing else block, providing it followed the "double v" that
declares that variable.

Obviously, I couldn't leave those lines in the program, so I tried
replacing the two lines with a simple "sleep(1)" and found that the bug
still disappeared, although the sleep() function needed to be called inside
the if block to work, unlike the original test code.  Of course, although
this do-nothing code would not print strange messages for users, it's still
unacceptable because it would slow the program down tremendously, but it
proved that whatever I put there doesn't have to do anything useful to fix
the bug.  I tried putting something like "1+1" in there, but that didn't
work (it was probably optimised out by the compiler, since the result
isn't used).  I finally found that placing the following line in the
beginning of the block did the trick:

	    fflush(stdout);

Of course this line serves no purpose, but it causes the bug to disappear.
I'm not happy with this solution, because it doesn't address the problem
directly, and I think there ought to be a better way.  If anyone would like
to tackle this, and can find the real problem, please e-mail me.

Of course, this is not likely the only bug still present, and any and
all bug fixes (or bug reports) are welcome.

Chuck
<cmartin@bigfoot.com>

