[comp.lang.modula2] How to write NEW?

jan@janhh.hanse.de (Jan Willamowius) (04/19/91)

It looks like Wirth is using different ways to allocate memory
in different versions of his books. Sometimes he uses
'Allocate(Var,SIZE(Type)' and sometimes 'NEW(Var)'.

I like the second way better, but my compiler only supports Allocate.
So, is there a way to write a NEW (and DISPOSE, of course) ?

This is how far I got:
--- DEF ---
DEFINITION MODULE Storage;
FROM Heap IMPORT Allocate, Deallocate;
FROM SYSTEM IMPORT ADDRESS;

PROCEDURE NEW(VAR p : ADDRESS);

PROCEDURE DISPOSE(VAR p : ADDRESS);

END Storage.
--- IMP --
IMPLEMENTATION MODULE Storage;
FROM Heap IMPORT Allocate, Deallocate;
FROM SYSTEM IMPORT ADDRESS;

PROCEDURE NEW(VAR p : ADDRESS);
BEGIN
  Allocate(p,SIZE(p^));
END NEW;

PROCEDURE DISPOSE(VAR p : ADDRESS);
BEGIN
  Deallocate(p,SIZE(p^));
END DISPOSE;

BEGIN
END Storage.

The problem is that p 'looses' its type in the conversion to ADDRESS and
only a WORD is Allocated (ADDRESS is POINTER TO WORD).

Any ideas ?

Greetings, Jan

--
Jan Willamowius, Nienredder 6, 2000 Hamburg 54, Germany
E-Mail: jan@janhh.hanse.de

S.J.Lovatt@massey.ac.nz (S.J. Lovatt) (04/21/91)

From: jan@janhh.hanse.de (Jan Willamowius)
>
> It looks like Wirth is using different ways to allocate memory
> in different versions of his books. Sometimes he uses
> 'Allocate(Var,SIZE(Type)' and sometimes 'NEW(Var)'.
>
> I like the second way better, but my compiler only supports Allocate.
> So, is there a way to write a NEW (and DISPOSE, of course) ?

< Code omitted >

> PROCEDURE NEW(VAR p : ADDRESS);
> BEGIN
>   Allocate(p,SIZE(p^));
> END NEW;
>
> The problem is that p 'looses' its type in the conversion to ADDRESS and
> only a WORD is Allocated (ADDRESS is POINTER TO WORD).
>
> Any ideas ?

Unfortunately, it is impossible to write NEW in Modula-2. One of the
reasons I prefer Modula-2 over Pascal (for instance) is that almost all of
the Modula-2's library procedures can be written in Modula-2. The
exceptions which now remain are things like VAL, INC etc which translate
directly into inline code on many compilers anyway.

If I desperately wanted to do NEW, DISPOSE, etc, I would tack a macro
processor on the front of my Modula-2 compiler (eg a C preprocessor) and
define NEW as a macro which expands to 'Allocate (p,SIZE(p^))', thus not
losing the size of p^. Modula-2 purists may feel free to cringe. Actually,
I don't usually do this when programming in Modula-2 as I'd have to give
up my integrated environment, although I do it a lot when programming in
Fortran on Unix systems. What I sometimes do if I am doing a lot of
allocating and deallocating is something like this:

TYPE     WidgetPtr = POINTER TO Widget;
         Widget = RECORD ...... END;

PROCEDURE NEWWidget (VAR p : WidgetPtr);
BEGIN
   Allocate (p,SIZE(p^));
END NEWWidget;

If your compiler supports inline procedures, this is equivalent to the
macro solution in space and time efficiency, while still being type-safe.

- Simon


-- 
Simon Lovatt            | S.J.Lovatt@massey.ac.nz |
Dept of Biotechnology   |                         |
Massey University, N.Z. |                         |

gmurray@ibmpcug.co.uk (G Murray) (04/21/91)

In article <5122672@janhh.hanse.de> jan@janhh.hanse.de (Jan Willamowius) writes:
> It looks like Wirth is using different ways to allocate memory
> in different versions of his books. Sometimes he uses
> 'Allocate(Var,SIZE(Type)' and sometimes 'NEW(Var)'.
> 
> I like the second way better, but my compiler only supports Allocate.
> So, is there a way to write a NEW (and DISPOSE, of course) ?>

 [Code Deleted]
 
> The problem is that p 'looses' its type in the conversion to ADDRESS and
> only a WORD is Allocated (ADDRESS is POINTER TO WORD).


  I don't think that you will be able to do it. NEW and DISPOSE are normally
built in functions, that require ALLOCATE and DEALLOCATE to be IMPORTed. In
my experience the compiler normally translates calls to NEW and DISPOSE into
appropriate calls to ALLOCATE and DEALLOCATE. So, without this 'inside
information' available to the compiler, I don't think that a library function
will be able to do it. 

Graham Murray				email gmurray@ibmpcug.co.uk
Senior Programmer			      gmurray@cix.compulink.co.uk
Gravatom Technology Ltd			voice +44 329 823986


-- 
Automatic Disclaimer:
The views expressed above are those of the author alone and may not
represent the views of the IBM PC User Group.
-- 

soper@encore.UUCP (Pete Soper,Cary NC,9194813730,9193624635) (04/22/91)

From article <5122672@janhh.hanse.de>, by jan@janhh.hanse.de (Jan Willamowius):
[description of "new" implementation omitted]
> The problem is that p 'looses' its type in the conversion to ADDRESS and
> only a WORD is Allocated (ADDRESS is POINTER TO WORD).
> 
> Any ideas ?

If you have the source to your compiler, yes, otherwise no. The problem is
that at the point "new" is invoked, the compiler needs to pass the size of
the item to be allocated as a hidden parameter. So if you can modify your
compiler you can arrange for new to be an intrinsic and pass the size along.
Otherwise you are out of Shlitz. Without changing the compiler you *must*
add a second parameter to new to pass the item size.
-----------------------------------------------------------------------
Pete Soper (soper@encore.com)                           +1 919 481 3730
Encore Computer Corp, 901 Kildaire Farm Rd, bldg D, Cary, NC 27511  USA

soper@encore.UUCP (Pete Soper,Cary NC,9194813730,9193624635) (04/22/91)

In my previous posting I didn't spell Schlitz correctly. Sorry. In any case,
I meant "you are out of luck".
-----------------------------------------------------------------------
Pete Soper (soper@encore.com)                           +1 919 481 3730
Encore Computer Corp, 901 Kildaire Farm Rd, bldg D, Cary, NC 27511  USA

eepjm@cc.newcastle.edu.au (04/22/91)

In article <5122672@janhh.hanse.de>, jan@janhh.hanse.de (Jan Willamowius)
writes:
> It looks like Wirth is using different ways to allocate memory
> in different versions of his books. Sometimes he uses
> 'Allocate(Var,SIZE(Type)' and sometimes 'NEW(Var)'.
> 
> I like the second way better, but my compiler only supports Allocate.
> So, is there a way to write a NEW (and DISPOSE, of course) ?
> 
I wasn't going to respond to this at first, on the grounds that it's a
common problem for beginners and that surely somebody else would quickly
sort out Jan's problem ... then I watched in horror as a whole string of
responses seemed to confuse the issue even more.  Either a lot of people
have misunderstood the question, or I have.

The answer is actually quite simple, it's only the documentation that's
bad.  EVERY Modula-2 compiler supports NEW and DISPOSE (if you find one
that doesn't, you've been cheated) in the following way.  When NEW(Var)
appears in your source, it is automatically translated by the compiler
into Allocate(Var,SIZE(Var^)).  The catch is - and this is where almost all
first-time users of Modula-2 are trapped - that you have to remember to
import Allocate from module Storage (or elsewhere).  That is, you have to
write something like:

      FROM Storage IMPORT Allocate, Deallocate;

        .
        .
        NEW(p);

i.e. you have to call Allocate even though there is no explicit call to
Allocate in your program.  (By the way, some compilers spell it Allocate,
and others use the upper-case ALLOCATE).  NEW is not a procedure, even though
the syntax makes it look like one.  It's just a shorthand way of setting up
a call to Allocate.

By the way, you are perfectly free to re-write your own version of
Allocate if you don't like the one supplied with your compiler.  (I have
done this myself, since the version of module Storage supplied with the
FTL compiler doesn't have critical section protection, and crashes in
multitasking applications).

Hope this helps.

Peter Moylan                   eepjm@cc.newcastle.edu.au

warwick@cs.uq.oz.au (Warwick Allison) (04/22/91)

Use the C preprocessor.

#define NEW(p) ALLOCATE(p,SIZE(p^))

That, I think is the only solution, unless you want to change NEW to
use it as NEW(a,a^), in which case just implement:

	PROCEDURE NEW(VAR a:ADDRESS; VAR adata:ARRAY OF BYTE);

and hope that you compiler will not actually dereference a to get a^ since
it does not actually need to know the data.

How about that for an ugly kludge?

Warwick.
--
  _-_|\       warwick@cs.uq.oz.au
 /     *  <-- Computer Science Department,
 \_.-._/      University of Queensland,
      v       Brisbane, AUSTRALIA.

soper@encore.UUCP (Pete Soper,Cary NC,9194813730,9193624635) (04/22/91)

From article <1991Apr22.155056.10010@cc.newcastle.edu.au>, by eepjm@cc.newcastle.edu.au:
> 
> The answer is actually quite simple, it's only the documentation that's
> bad.  EVERY Modula-2 compiler supports NEW and DISPOSE (if you find one
> that doesn't, you've been cheated) in the following way.  When NEW(Var)

  There are lots of cheated folks out there in that case. Compilers
implementing the language described by edition three of the Wirth book do not
contain NEW and DISPOSE. This is another case where Wirth fiddled with the
language with little concern for the impact of the fiddling. While Wirth
is of course free to do as he likes I wish when he went from the second to
the third edition he had changed the name of the language to really cut down
on the confusion :-)
-----------------------------------------------------------------------
Pete Soper (soper@encore.com)                           +1 919 481 3730
Encore Computer Corp, 901 Kildaire Farm Rd, bldg D, Cary, NC 27511  USA

icsu8209@nero.cs.montana.edu (Glassy) (04/23/91)

In article <14627@encore.Encore.COM> soper@encore.UUCP (Pete Soper,Cary NC,9194813730,9193624635) writes:
>From article <1991Apr22.155056.10010@cc.newcastle.edu.au>, by eepjm@cc.newcastle.edu.au:
>> 
>> The answer is actually quite simple, it's only the documentation that's
>> bad.  EVERY Modula-2 compiler supports NEW and DISPOSE (if you find one
>> that doesn't, you've been cheated) in the following way.  When NEW(Var)
>
>  There are lots of cheated folks out there in that case. Compilers
>implementing the language described by edition three of the Wirth book do not
>contain NEW and DISPOSE. This is another case where Wirth fiddled with the

Really?  I'm surprised.  Truly.  I've used the shareware FST compiler,
which is based on 3rd ed. PIM2 (according to the documentation).  The
FST documentation didn't explicitly -say- that NEW and DISPOSE were
translated into corresponding calls to ALLOCATE and DEALLOCATE (i
think!), but -did- say that if you wanted to use NEW and DISPOSE, you
had to import {DE}ALLOCATE from Storage.

The docs for the StonyBrook QuickMod compiler I've used said the same.

Just a couple of data points, I suppose...

>Pete Soper (soper@encore.com)                           +1 919 481 3730
>Encore Computer Corp, 901 Kildaire Farm Rd, bldg D, Cary, NC 27511  USA

Ben.Coleman@p0.f11.n277.z1.fidonet.org (Ben Coleman) (04/25/91)

EE>The answer is actually quite simple, it's only the documentation that's
EE>bad.  EVERY Modula-2 compiler supports NEW and DISPOSE (if you find one
EE>that doesn't, you've been cheated) in the following way.

Isn't "you've been cheated" a bit strong?  The only reference to NEW and 
DISPOSE that I can find in PIM2(3rd edition) appears on page 76:

    "In some implementations, the statement Allocate(p0, SIZE(Node)) can be
     abbreviated as NEW(p0)."

There doesn't seem to be any implication that all implementations *should* 
support it, just a note that some do.

Anyone know if NEW and DISPOSE appear in the ISO standard?

Ben
 * SM 1.00 ----- * Email To: 70176.1334@compuserve.com



--  
uucp: uunet!m2xenix!puddle!277!11.0!Ben.Coleman
Internet: Ben.Coleman@p0.f11.n277.z1.fidonet.org

eepjm@cc.newcastle.edu.au (04/26/91)

In article <1991Apr22.155056.10010@cc.newcastle.edu.au>, I wrote:
> 
> The answer is actually quite simple, it's only the documentation that's
> bad.  EVERY Modula-2 compiler supports NEW and DISPOSE (if you find one
> that doesn't, you've been cheated) in the following way.  When NEW(Var)
> appears in your source, it is automatically translated by the compiler

My humble apologies for getting this wrong.  It seems that there *are*
compilers which fail to support NEW and DISPOSE, and that they don't violate
the de facto standard described by the third edition of Wirth's book.  (To
see this, you have to note carefully what Wirth *didn't* say).

I still believe that the people who bought those compilers have been
cheated, but I shouldn't have jumped in and assumed that other people
didn't understand the language.  (Creeps out, red-faced).

Peter Moylan                   eepjm@cc.newcastle.edu.au

borchert@laborix.mathematik.uni-ulm.de (Andreas Borchert) (05/01/91)

In article <14627@encore.Encore.COM>, soper@encore.UUCP (Pete Soper,Cary NC,9194813730,9193624635) writes:
|> From article <1991Apr22.155056.10010@cc.newcastle.edu.au>, by eepjm@cc.newcastle.edu.au:
|> > 
|> > The answer is actually quite simple, it's only the documentation that's
|> > bad.  EVERY Modula-2 compiler supports NEW and DISPOSE (if you find one
|> > that doesn't, you've been cheated) in the following way.  When NEW(Var)
|> 
|>   There are lots of cheated folks out there in that case. Compilers
|> implementing the language described by edition three of the Wirth book do not
|> contain NEW and DISPOSE. This is another case where Wirth fiddled with the
[...]

Wirth declares NEW in the 3rd edition to be optional. Chapter 21, p. 76:

"In some implementations, the statement Allocate(p0, SIZE(Node)) can
be abbreviated as NEW(p0)."

In fact, nearly every Modula-2 compiler accepts NEW and DISPOSE.
Further, NEW & DISPOSE are expected to be part of the coming standard.

-- 
Andreas Borchert        |   Internet: borchert@mathematik.uni-ulm.de
Universitaet Ulm, SAI   |             postmaster@uni-ulm.de
Oberer Eselsberg        |   Bitnet:   borchert@dulruu51.bitnet
D-7900 Ulm, Germany     |   X.400:    S=borchert; OU=rz; P=uni-ulm; A=dbp; C=de

soper@encore.UUCP (Pete Soper,Cary NC,9194813730,9193624635) (05/03/91)

From article <1991May1.122959.3716@informatik.uni-ulm.de>, by borchert@laborix.mathematik.uni-ulm.de (Andreas Borchert):
> In article <14627@encore.Encore.COM>, soper@encore.UUCP (Pete Soper,Cary NC,9194813730,9193624635) writes:
   [ some omissions ]
> |>   There are lots of cheated folks out there in that case. Compilers
> |> implementing the language described by edition three of the Wirth book do not
> |> contain NEW and DISPOSE. This is another case where Wirth fiddled with the
> [...]
> 
> Wirth declares NEW in the 3rd edition to be optional. Chapter 21, p. 76:
> 
> "In some implementations, the statement Allocate(p0, SIZE(Node)) can
> be abbreviated as NEW(p0)."
> 
> In fact, nearly every Modula-2 compiler accepts NEW and DISPOSE.
> Further, NEW & DISPOSE are expected to be part of the coming standard.

  The first "3rd edition" single pass compiler (written by Wirth himself and 
others at ETHZ), did not implement NEW and DISPOSE. This compiler went out to 
the four corners of the globe and was the basis for compilers sold or given
away in dozens of forms. Since the lack of NEW and DISPOSE was one of many
ass-pains for folks moving code from "2nd edition" compiler environments it
certainly makes sense that this was retrofitted commonly and so "nearly every 
Modula-2 compiler accepts NEW and DISPOSE".  Folks implementing the 3rd edition
language from scratch probably had backward compatibility in mind from the 
start and would tend to include this "option" without hesitation.
  I think we are approaching violent agreement about this subject so let's 
move on.
  Speaking of the coming standard, what was the final decision about forward
declarations? That is, does the standard allow for single pass implementations
or did they stand firm and reject this change which came with the 2nd edition/
3rd edition transition?
-----------------------------------------------------------------------
Pete Soper (soper@encore.com)                           +1 919 481 3730
Encore Computer Corp, 901 Kildaire Farm Rd, bldg D, Cary, NC 27511  USA