Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #47141

RESIZE boundary conditions

From anton@mips.complang.tuwien.ac.at (Anton Ertl)
Newsgroups comp.lang.forth
Subject RESIZE boundary conditions
Date 2016-05-15 11:26 +0000
Organization Institut fuer Computersprachen, Technische Universitaet Wien
Message-ID <2016May15.132631@mips.complang.tuwien.ac.at> (permalink)

Show all headers | View raw


On most Forth systems RESIZE ( addr1 u -- addr2 ior) is implemented by
calling the C library's realloc(void *ptr, size_t size).  There are
at least two interesting boundary cases:

1) What if addr1=0?

The C99 and C11 C standards cover this clearly:

|If ptr is a null pointer, the realloc function behaves like the malloc
|function for the specified size.

That is useful: If there is a variable that contains an address for a
variable-size memory region, you can just initialize it to 0, and
everything will be fine.

The Forth standard requires that a-addr1 is "previously allocated by
ALLOCATE or RESIZE".

That means that one has to initialize the variable above with an
ALLOCATEd address for memory that will never be used, or
alternatively, always check for 0 before calling RESIZE.

Testing this with Gforth, SwiftForth, and VFX (on Linux), 0 50 RESIZE
produces an address and ior=0 on all of them.  So we might add the
provision for allowing addr1=0 to the standard as common practice.

2) What if u=0?

The Forth standard says nothing particular about this situation.
Given that 0 is sensible input, I expect that this should just work,
i.e., return ior=0; I don't care that much about the address in this
case.  However, all Forth systems I tested (Gforth (except my private
bug-fixed version), SwiftForth, and VFX) return a non-zero ior (VFX
also returns addr2=-1, while the standard requires addr2=addr1 in the
ior!=0 case).  Why is that?

C99 says:
|If the realloc function returns a null pointer when size is zero and
|ptr is not a null pointer, the object it pointed to has been freed.
|[...]
|The realloc function returns either a null pointer or a pointer to the
|possibly moved allocated space.

Now the glibc (Linux) realloc() frees the object and returns a null
pointer when you call realloc(...,0).  Apparently all three Forth
systems interpret that null pointer as indication of failure (like for
malloc()), not as a valid result for realloc(...,0).  But IMO they
should treat it as a valid result.

That brings me to my main question: Are there Forth programs that fail
if "addr 0 RESIZE" returns 0 0?

Anyway, the story is not yet at an end: C11 tightened the
specification of realloc().  It now says:

|The realloc function returns a pointer to the new object (which may
|have the same value as a pointer to the old object), or a null pointer
|if the new object could not be allocated.

So if the glibc realloc() implemented the C11 standard, the three
Forth systems would work as I expect them to even for "addr 0 resize".
But C99-compliant libcs will be around for quite some time yet, so we
have to work around that.  There are two possible workarounds:

1) Check for u=0 if the result of the realloc() is null, and in that
case, return 0 0.

2) Check for u=0, and in that case use free() and malloc() (or, on the
Forth level, FREE and ALLOCATE) instead of realloc().  At least glibc
returns a non-null pointer for malloc(0), although the C standards do
not clearly require that, either.  On the Forth level that workaround
would look like:

: resize ( addr1 u -- addr2 ior )
  dup if
    resize
  else
    drop dup if free then 0 allocate rot or
  then ;

The benefit of this variant is that it works also for Forth programs
that don't expect addr2=0.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2016: http://www.euroforth.org/ef16/

Back to comp.lang.forth | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

RESIZE boundary conditions anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-05-15 11:26 +0000
  Re: RESIZE boundary conditions ruvim.pinka@gmail.com - 2016-05-15 06:46 -0700
    Re: RESIZE boundary conditions anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-05-15 17:08 +0000
  Re: RESIZE boundary conditions november.nihal@gmail.com - 2016-05-15 09:13 -0700
    Re: RESIZE boundary conditions Albert van der Horst <albert@cherry.spenarnc.xs4all.nl> - 2016-05-15 18:23 +0000
    Re: RESIZE boundary conditions anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-05-16 13:13 +0000
      Re: RESIZE boundary conditions Hans Bezemer <the.beez.speaks@gmail.com> - 2016-05-16 15:23 +0200
        Re: RESIZE boundary conditions anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-05-16 14:01 +0000
        Re: RESIZE boundary conditions hughaguilar96@gmail.com - 2016-05-16 14:14 -0700
  Re: RESIZE boundary conditions Albert van der Horst <albert@cherry.spenarnc.xs4all.nl> - 2016-05-15 18:13 +0000
    Re: RESIZE boundary conditions anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-05-16 10:32 +0000
      Re: RESIZE boundary conditions Albert van der Horst <albert@cherry.spenarnc.xs4all.nl> - 2016-05-16 22:38 +0000
  Re: RESIZE boundary conditions Hans Bezemer <the.beez.speaks@gmail.com> - 2016-05-16 14:54 +0200

csiph-web