Since the result of SWI OS_Word is written to the block pointed to by
R1 instead of returned in a register, the return value of
_kernel_osword might reasonably be expected to indicate only success
or failure. However, having disassembled the relevant part of the
shared C library (in the absence of decent documentation), this
function appears to be returning the value of R1!
A simple test of calling OS_Word from BASIC indicates that the value
of R1 is preserved by this SWI, and therefore _kernel_osword has
effectively cast its 'int *data' argument to type 'int'. Even if the
return value were the appropriate type, I can't see any point in
_kernel_osword returning the address of the parameter block, because
it is already known to the caller. Furthermore, this seems to be a
dangerous policy because if bit 31 of the address of the parameter
block is set then _kernel_osword will return a negative value despite
having succeeded!
IMO this should have been addressed when updating RISC OS for 32 bit
modes. Is it likely that anyone (ab)uses the return value of
_kernel_osword by casting it back to a pointer? If not then it would
be more in keeping with other "kernel.h" functions to return the value
of R0 (reason code). Otherwise this function should at least be
flagged as problematic.
Other dodginess in this area concerns the _kernel_oswrch and
_kernel_osbput functions, which rely upon SWIs XOS_WriteC and XOS_BPut
returning a positive value in R0 unless they set the overflow flag to
indicate an error. Isn't this a foolish assumption? The PRM documents
those SWIs as preserving the entry value of R0, which suggests that
calling _kernel_oswrch or _kernel_osbput with a negative character
code could make them appear to fail.
All of this makes me think that relying on return values >= 0 to
indicate success may be a lost cause, and it would be safer to check
explicitly for -1 or -2. :-(
--
Christopher Bazley
> chrisbazley wrote:
[snip]
>> _kernel_osbput functions, which rely upon SWIs XOS_WriteC and XOS_BPut
>> returning a positive value in R0 unless they set the overflow flag to
>> indicate an error. Isn't this a foolish assumption? The PRM documents
> It's a foolish assumtion to test for a negative value with the AI
> documentation explicitly tells you to test for -1 or -2.
If you are referring to the same header file as me, it doesn't TELL
you to do anything. It simply describes two of the many int values
which are not ">= 0 if the call succeeds".
>> All of this makes me think that relying on return values >= 0 to
>> indicate success may be a lost cause, and it would be safer to check
>> explicitly for -1 or -2. :-(
> Exactly, just as the documentation tells you to do.
I would be extremely surprised if there is no code in existence where
the programmer has done something like 'if (_kernel_osword(2, ¶m)
>= 0)' to check for success - not least because it is less typing than
'if ((e = _kernel_osword(2, ¶m)) != _kernel_ERROR && e != -1)'.
It is perfectly reasonable in most circumstances to assume that 'not
success' means 'failure'.
--
Chris Bazley
Star Fighter 3000: http://starfighter.acornarcade.com/