title: /STRING question: can /STRING return a negative value? brief-answer: yes recommended-implementation: : /STRING ( c-addr1 u1 n -- c-addr2 u2 ) TUCK - >R CHARS + R> ; more-detailed-question: > 17.6.1.0245 /STRING "slash-string" STRING > ( c-addr1 u1 n -- c-addr2 u2 ) > Adjust the character string at c-addr1 by n characters. The resulting > character string, specified by c-addr2 u2, begins at c-addr1 plus n > characters and is u1 minus n characters long. What happens when n>u1, that is, what u2 must be when u1 minus n is less than zero? ( Elko Tchernev:) > There is a very big controversy - the u2 that /STRING returns is an > _unsigned_ number. All string words use an unsigned length. Therefore, > if in some case /STRING returns an -1, it is actually the MAXINT. longer-answer: it may be (and has been) argued what the standard was intended to mean, but the newsgroup has (almost?) reached a consensus that in a good system /STRING must return u1-n, even if it is negative. fully-detailed-answer: There have been two opinions. 1. ( Michael Gassanenko:) The words "plus" and "minus" in 17.6.1.0245 mean the functionalities of 6.1.0120 + "plus" and 6.1.0160 - "minus" respectively. And 6.1.0120 + "plus" and 6.1.0160 - "minus" return values of type n|u. There indeed is an ambiguous condition when /STRING returns negative length, but what is ambiguous is not the result (a cell containing a negative number), but interpretation of that result as an unsigned number (the interpretation depends on the number of bits in a cell etc.) 2. ( Anton Ertl:) > /STRING has the stack effect > > ( c-addr1 u1 n -- c-addr2 u2 ) > > So if n>u1, the result is undefined (since u2 cannot be <0). If you > want to check if /STRING underflows, you have to do it on the input > operands, if you want your program to be standard: > > 2dup u< over 0< 0= and if > ... \ deal with underflow > else > /string > then > > or somesuch. > > Nonetheless, I believe that, in a high-quality implementation > > ( c-addr u ) n /STRING -n /STRING > > should produce c-addr u for any n. I.e., that the /STRING > implementation of Gforth, SwiftForth, and VFX is the better one (and > it's also faster). more-discussion: Correct implementation of a /STRING that returns an empty string when n>u1 is not trival. At first, you must not put checks on the output result since the length of string may be greater than MAX-N (numbers greater than MAX-N will be interpreted by 0< as negative). You might write OVER MIN /STRING but here you again apply MIN that requires two signed inputs to a (unsigned, signed) pair. So the definition becomes \ /STRING that returns an empty string when n>u1 \ !!! Returning an empty string when n>u1 *is not* the \ recommended behaviour for /STRING !!! : /STRING0 ( c-addr1 u1 n -- c-addr2 u2 ) DUP 0> IF OVER MIN THEN TUCK - >R CHARS + R> ; page-written-by: mlg