How can this error happen?
Pages: 1 2
Dave Higton (1515) 3526 posts |
One of the apps in my heating control system sometimes gives “Unknown or missing variable at line 7070” on start-up, reported by:
Here are line 7070 and its predecessor:
How can that error happen? |
nemo (145) 2546 posts |
Execution has fallen into the FN from an earlier line – DEF is identical to REM for falling execution, so this construction is legal: DEFFNfourargs(A%,B%,C%,D%) DEFFNthreeargs(A%,B%,C%):LOCALD% DEFFNtwoargs(A%,B%):LOCALC%,D% DEFFNonearg(A%):LOCALB%,C%,D% =A%+B%+C%+D% Tee hee. |
Steve Fryatt (216) 2105 posts |
At a guess, because something is wrong before line 7060 such that execution arrives at it linearly. Consider the following:
I think that gives the same effect that you’re seeing. I can’t remember if BBC BASIC allows single-line function definitions, but I think it does and – in that case – the So the question that you need to ask is: “why is my code running into line 7060?” |
Dave Higton (1515) 3526 posts |
The previous three lines are the corresponding FNmax() function and a blank line. So 7040 is like 7070 but with the a% and b% swapped at the two exits. Unless it’s possible to run from line 7070 into the next function, it equally isn’t possible to run into 7060. And I don’t have any GOTOs anywhere. |
Steve Drain (222) 1620 posts |
Line 7060 starts with a colon. That means that |
nemo (145) 2546 posts |
I assumed that was just Zap’s redrawing – it always does that to confuse people. ;-) When Zap says 10 : DEF that’s fine. When 10 : DEF then it’s not fine, obvs! |
Steve Drain (222) 1620 posts |
Quite a useful construction sometimes. I have a neat alternative that allows any number of parameters to be |
nemo (145) 2546 posts |
Indulge an old man and add 7059 STOP and see if it behaves the same. |
nemo (145) 2546 posts |
Oh go on… and if it involves Basalt assume the rolling of eyes and tossing of pens. |
nemo (145) 2546 posts |
Oh. Is 7070 the last line of the program? |
Steve Drain (222) 1620 posts |
Never used Zap, but that still leaves the mystery error. |
Dave Higton (1515) 3526 posts |
No, there are many more lines. As for the colons: they are a consequence of Zap’s conversion from BASIC to text. My apologies, it never occurred to me that the text was in any way abnormal. Just for completeness, here are the five lines in question: 7030 : DEF FNmax(a%, b%) 7040 : IF a% >= b% THEN = a% ELSE = b% 7050 : 7060 : DEF FNmin(a%, b%) 7070 : IF a% >= b% THEN = b% ELSE = a% The line numbers are multiples of 10, and the last line is 9550. |
Steve Drain (222) 1620 posts |
If you insist. ;-) This only works with RO5 versions of BASIC: PRINT FNtest,9 END DEFFNtest PROCdata LOCAL n%:n%=5:REM default value IF FNdata THEN READ n%:READ value if there is data PROCdata =n% DEFPROCata LOCAL k%:DIM k% LOCAL TRUE:REM get stack pointer SWAP !&85F4,k%!20:REM swap data pointer and return address ENDPROC DEFFNdata =?!&85F4=44:REM true if data pointer is to a comma Edit: There are some caveats, so no picking.
|
nemo (145) 2546 posts |
There’s no part of that that isn’t horrific, and you should all be thoroughly ashamed. |
Jon Abbott (1421) 2651 posts |
Possibly memory corruption. Could another variable be overrunning its DIM’d area and corrupting the next variable? |
Rick Murray (539) 13840 posts |
I concur with nemo. Magic numbers are not your friend… |
nemo (145) 2546 posts |
TBH it was |
nemo (145) 2546 posts |
Jon said
Always possible. But like blaming a previously undiscovered OS bug, it usually isn’t… and it’s not possible to corrupt the memory between the FN that set the vars and the IF that uses them (unless things have got very bad). At the risk of repeating myself, concatenate the lines and see what happens:
It will behave differently, I suspect. |
Steve Drain (222) 1620 posts |
Good, init?
They are my friends, but they are scary, so need to be hidden away and well documented.
No. Neither are defined, but they have both been the same for 30 years. You take a commensurate risk using such knowledge. The use of I will not mention any of the others, for fear of causing a melt down. ;-) |
nemo (145) 2546 posts |
Slight non-sequitor, but for some reason this popped into mind: DIMM%3 Q%=M%:PRINT"Unsurprisingly 1=";FNodd(1) Q%=0:PRINT"Surprisingly 99=";FNodd(99) END DEFFNodd(!Q%)=!M% Implicit LOCALness is one thing, but immutability of PROC/FN chains is another. |
Steve Drain (222) 1620 posts |
My favourite obscure gotcha. |
Rick Murray (539) 13840 posts |
Wow. Now maybe we can understand why writing a BASIC compiler is hard. ;-) |
Rick Murray (539) 13840 posts |
Are “the others” documented anywhere? Watashi kininarimasu! |
Steve Drain (222) 1620 posts |
If you mean ‘magic numbers’ then, yes, in my StrongHelp BASIC manual and elswhere. Some workspace numbers are available legally through From assembly you would use the offsets, not absolute values, which you can find in the BASIC source. Over time a handful of the more obscure ones have changed to accomodate changes to RISC OS, but there would be no purpose in changing all the rest. The values put on the stack by various keywords can be found from the BASIC source. It would probably require some significant rewriting to invalidate those. If you mean ’ nefarious purposes’ then, no, because I fear that releasing them would cause havoc. ;-) Using exact ‘magic numbers’ directly from BASIC is a bit contrived and open to being invalidated. It is an exercise, for amusement. The same things can be done with assembler more quickly and with a fair amount of security. That is where Basalt stands. |
nemo (145) 2546 posts |
As for the magic numbers, they do and have changed. I’ve said it before – don’t move things if you don’t have to… and also don’t use magic numbers if it can be avoided. |
Pages: 1 2