( u "<spaces>name" -- )

Skip leading space delimiters. Parse name delimited by a space. Create a definition for name, with the execution semantics defined below. Reserve u address units at an aligned address. Contiguity of this region with any other region is undefined.

name Execution:

( -- a-addr )

a-addr is the address of the space reserved by BUFFER: when it defined name. The program is responsible for initializing the contents.



BUFFER: provides a means of defining an uninitialized buffer. In systems that use a single memory space, this can effectively be defined as:

: BUFFER: ( u "<name>" -- ; -- addr )

However, many systems profit from a separation of uninitialized and initialized data areas. Such systems can implement BUFFER: so that it allocates memory from a separate uninitialized memory area. Embedded systems can take advantage of the lack of initialization of the memory area while hosted systems are permitted to ALLOCATE a buffer. A system may select a region of memory for performance reasons. A detailed knowledge of the memory allocation within the system is required to provide a version of BUFFER: that can take advantage of the system.

It should be noted that the memory buffer provided by BUFFER: is not initialized by the system and that if the application requires it to be initialized, it is the responsibility of the application to initialize it.


This implementation depends on children of CREATE returning an aligned address. Other memory location techniques require implementation-specific knowledge of the underlying Forth system.

: BUFFER: \ u "<name>" -- ; -- addr
\ Create a buffer of u address units whose address is returned at run time.


T{ 127 CHARS BUFFER: TBUF2 -> }T \ Buffer is aligned
T{ TBUF1 ALIGNED -> TBUF1 }T \ Buffers do not overlap
T{ TBUF2 TBUF1 - ABS 127 CHARS < -> <FALSE> }T \ Buffer can be written to
: TFULL? ( c-addr n char -- flag )
     OVER I C@ = AND

T{ TBUF1 127 CHAR * FILL   ->        }T
T{ TBUF1 127 CHAR * TFULL? -> <TRUE> }T

T{ TBUF1 127 0 FILL   ->        }T
T{ TBUF1 127 0 TFULL? -> <TRUE> }T


ruvavatar of ruv the confusing namesRequest for clarification2018-09-11 18:09:27

What was the rationale to have BUFFER and BUFFER: words at the same time? It is confusing that so similar names refer to so different concepts. Perhaps BUFFER should have been made obsolete?

ruvavatar of ruv

Another issue with this name is a colon at the end. There are many standard parsing words that take one argument from the input. Some of them do not have a colon at the end, but some other (mostly new) have a colon. What is the rule? if CONSTANT does not have a colon in its name, why BUFFER: does?

It looks like a strange inconsistency in the naming conventions.

AntonErtlavatar of AntonErtl

All the new names with : at the end were introduced because the corresponding names without colon already have a conflicting meaning in a widely used system. I know this for sure for the field words and for {:, for BUFFER: I don't remember any discussion about the name.

StephenPelcavatar of StephenPelc

At the time (early 1990s) it was expected that BLOCK and friends would slowly die away. Especially with the rise of retro-computing BLOCK and friends remain healthy.

Reply New Version

AntonErtlavatar of AntonErtl Revise Rationale of Buffer:Proposal2019-07-06 15:45:25

This contribution has been moved to the proposal section.

AntonErtlavatar of AntonErtl

This reply has been moved to the proposal section.
Reply New Version

ruvavatar of ruv Address between runsRequest for clarification2019-07-09 12:54:28

It seems this word specification intents that a compiled program can be saved into an image and run from the image multiple times.

May a system provide different addresses between runs?

1024 BUFFER: foo

foo CONSTANT bar
\ use bar in the code further

This code is either standard or not standard depending on the answer. If it is not standard, an ambiguous condition should be mentioned in the specification.

AntonErtlavatar of AntonErtl

The code is standard.

Images are not standardized, so what a system does on image creation and restoration is up to the system.

I think that it would be too restrictive to not support this kind of code (at least if FOO was an address in the dictionary), so systems will support it in some way, either by always restoring the image to the same addresses, or by supporting relocatable images.

E.g., Gforth supports relocatable images, so even though the address of FOO may change across image saving and restoring, BAR will work as intended. Some not so common uses do not work across image saving and restoring, though, e.g., if you compute a hash value from data that includes an address.

StephenPelcavatar of StephenPelc

Good catch. IMHO it is entirely sensible that children of BUFFER: may return different addresses on different runs. Apart from Anton's example, consider a buffer allocated from the heap. Heap allocation may vary from run to run.

Reply New Version