BBC BASIC
« Unexpected "No room" error »

Welcome Guest. Please Login or Register.
Jan 20th, 2018, 4:22pm


Cross-platform BBC BASIC (Win32, Linux x86, Android, Mac OS-X, Raspberry Pi)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Unexpected "No room" error  (Read 312 times)
hellomike
Junior Member
ImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 55
xx Unexpected "No room" error
« Thread started on: Mar 22nd, 2017, 1:26pm »

Hi,

Running on BB4W 6.02a, using a string function involving a numeric and less than 1MB free memory,
results in a "No room" error.
See below code which illustrates this.
Code:
   10 Size%=1050000:REM Works with 1040000
   20 DIM Mem% Size%
   30 REM Fill block with non-&00 chars
   40 FOR I%=0 TO Size%-1 STEP 4
   50   Mem%!I%=&41414141
   60 NEXT
   70 Mem%?Size%=0:REM Terminating &00 so I can use $$Mem%
   80 
   90 PRINT Size%, LEN$$Mem%, HIMEM-END-1024*1024
  100 PRINT RIGHT$($$Mem%)
  110 PRINT RIGHT$($$Mem%,1):REM Works without this line
  120 PRINT "Hello"
  130 END 


The output is:
Code:
   1050000   1050000     -1763
A

No room at line 110
>
 

Note that "A" is printed so the function 'RIGHT$($$Mem%)' works.

As far as I tested, the issue happens:
  1. when there is less than 1MB free space
  2. with string functions like LEFT$/RIGHT$/MID$(<string>,<numeric>) are involved

Is this a know issue or am I doing something wrong?
For what I need it for, I have a suitable workaround so it isn't urgent.

Thanks

Mike
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Unexpected "No room" error
« Reply #1 on: Mar 22nd, 2017, 4:07pm »

on Mar 22nd, 2017, 1:26pm, hellomike wrote:
Is this a know issue or am I doing something wrong?

By default BB4W provides 2 Mbytes of memory for your program, heap and stack (it's configurable). You are using up approximately half of that in the DIM statement, and then you are creating a temporary string of a similar length for use by the RIGHT$() function. That's all your free memory gone!

So the 'No room' error is neither "unexpected" nor an "issue", and you aren't doing anything "wrong" as such. It's simply that the default amount of available memory is insufficient for the program that you have listed.

In such a case I wouldn't spend any time analysing where the memory has gone, I would simply allocate more memory and not worry about it! For example making 10 megabytes available (which is still not a lot by modern standards) the program runs fine:

Code:
      HIMEM = PAGE + 10000000

      Size%=1050000:REM Works with 1040000
      DIM Mem% Size%
      REM Fill block with non-&00 chars
      FOR I%=0 TO Size%-1 STEP 4
        Mem%!I%=&41414141
      NEXT
      Mem%?Size%=0:REM Terminating &00 so I can use $$Mem%

      PRINT Size%, LEN$$Mem%, HIMEM-END-1024*1024
      PRINT RIGHT$($$Mem%)
      PRINT RIGHT$($$Mem%,1):REM Works without this line
      PRINT "Hello"
      END 

Richard.
« Last Edit: Mar 22nd, 2017, 6:19pm by Richard Russell » User IP Logged

hellomike
Junior Member
ImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 55
xx Re: Unexpected "No room" error
« Reply #2 on: Mar 23rd, 2017, 09:31am »

Thanks Richard.

However I don't get it. What temporary string is created?
Line 100 doesn't, as it works. Why would the statement in line 110 need to create a temporary string equal in length to $$Mem% (which indeed wouldn't have the space for)?

Thanks

Mike
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Unexpected "No room" error
« Reply #3 on: Mar 23rd, 2017, 10:27am »

on Mar 23rd, 2017, 09:31am, hellomike wrote:
Why would the statement in line 110 need to create a temporary string equal in length to $$Mem% (which indeed wouldn't have the space for)?

You are looking at things as a human would, rather than as the interpreter does! A human looks at these two statements and concludes that they are equivalent, so would be expected to behave identically:

Code:
      PRINT RIGHT$($$Mem%)
      PRINT RIGHT$($$Mem%,1) 

But the human is doing two things that the interpreter doesn't. Firstly he is 'looking ahead': in deciding what to do with the first parameter he considers the second parameter. Secondly he distinguishes between a constant value and an expression: because the second parameter is a constant he concludes that it is not necessary to create a temporary string.

The BBC BASIC interpreter does neither of these things. It parses the RIGHT$() function strictly left-to-right, so before the second parameter is even evaluated it has to decide what to do with the first parameter, and it makes no distinction between the second parameter being a constant and an expression.

So because the second parameter might be an expression rather than a constant, and because that expression might have the side-effect of modifying the first parameter, the interpreter has no choice but to make a temporary copy of the first parameter just in case!

This is one of the differences between a compiled language and an interpreted language. A compiler can 'look ahead': it can make decisions and perform optimisations based on the program as a whole. But an interpreter just plods through the program one element at a time, without knowing what comes next, and therefore must behave 'defensively'.

Only in a tiny minority of programs will evaluating the second parameter of the RIGHT$() function have the side-effect of modifying the first parameter. But it makes no difference how rare that circumstance is, to ensure that the correct result is returned the interpreter must assume it will happen and therefore makes a copy of the first parameter.

This sort of thing is going on all the time in BBC BASIC! For example I sometimes get asked why a simple statement like this can fail with a 'No room' error:

Code:
      array() = 1, 2 

The reason is basically the same as in your example. Before the interpreter even gets around to evaluating the expression to the right of the equals sign it has to assume that the result might be dependent on the original contents of the array. So, just in case, it copies the entire array into free memory, assigns the value of the right-hand-side to that copy, and then transfers the copy back into the original array.

That is quite an overhead, in both time and temporary memory usage, but if it didn't do that this statement would fail and produce the wrong result:

Code:
      array() = 1, array(0) 

Once again the circumstances in which this sort of problem occurs will be extremely rare, but it's not acceptable for BBC BASIC for make a mistake however rare they may be. So it behaves in such a way that the answer will always be correct.

If that means a 'No room' error that the programmer does not immediately understand that's just how it has to be!

Richard.

« Last Edit: Mar 23rd, 2017, 12:02pm by Richard Russell » User IP Logged

hellomike
Junior Member
ImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 55
xx Re: Unexpected "No room" error
« Reply #4 on: Mar 23rd, 2017, 12:21pm »

Awesome answer. Think I get it now.

So because in theory the 2nd parameter could be something like this (couldn't think of a more simple example):
Code:
      B$="ABC"
      PRINT RIGHT$(B$,FNappend)
      END

      DEF FNappend
      B$+="DEF"
      =1 

Correctly the output is 'C'.
If it wouldn't create the temporary string the wrong output would be 'F'.

And because RIGHT$(<string>) doesn't have the 2nd parameter, there is no need for the temporary string.

Quote:
If that means a 'No room' error that the programmer does not immediately understand that's just how it has to be!

Which also isn't a problem because Richard always gladly explains!

Thanks again.

Mike
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

Donate $6.99 for 50,000 Ad-Free Pageviews!


This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls