[comp.lang.fortran] Type punning in FORTRAN

matthias@mpx1.lanl.gov (Bjorn E. Matthias, M/S H831, 7-6241 or 7-7906) (10/16/89)

In article <1874@sunset.MATH.UCLA.EDU>, pmontgom@sonia.math.ucla.edu (Peter Montgomery) writes:
> In article <1989Oct13.090311.9760@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk 
> (P E Smee) writes:
>>
>>The need for a construct to permit type punning is clear, particularly
>>if you're doing 'systemmy' work.  
>>
>>This provides an explicit instruction to the compiler, and (more
>>importantly) a warning to future maintainers of the code, that you are
>>about to willfully, knowledgeably, and intentionally, cheat the data
>>typing and conversion rules.  Every serious language should have such a
>>thing.  (Unfortunately, it seems that most don't, sigh...)
>>
> 	If I read the June, 1989 draft F8X correctly, then the
> new TRANSFER intrinsic function (p. 13-51, section 13.13.108)
> will do precisely this.  The syntax is
> 
> 	result = TRANSFER(SOURCE, MOLD, SIZE) .
> 
> It "returns a result with a physical representation identical to that
> of SOURCE but interpreted with the type and type parameters of MOLD."
> The last argument, SIZE, is optional and affects the array shape
> of the result when SOURCE and MOLD have different sizes
> (e.g., double precision and character).
> 

If I am not mistaken, then this could be previously accomplished in
VAX FORTRAN with EQUIVALENCE between two variables of whatever types.
I have used this often and it appears that TRANSFER is different only
in that one truly has *two* pieces of data, two memory locations.
Sounds like a useful function, though I do not believe it really
introduces a "new" feature.
Forgive me if I am stating what is obvious to all others.
Regards,

Bjorn Matthias

BITNET : MATTHIAS@LAMPF

maine@elxsi.dfrf.nasa.gov (Richard Maine) (10/16/89)

In article <1131@mpx1.lanl.gov> matthias@mpx1.lanl.gov (Bjorn E. Matthias, M/S H831, 7-6241 or 7-7906) writes:

>> [.. cited discussion of F8x TRANSFER intrinsic ..]

>  If I am not mistaken, then this could be previously accomplished in
>  VAX FORTRAN with EQUIVALENCE between two variables of whatever types.
>  I have used this often and it appears that TRANSFER is different only
>  in that one truly has *two* pieces of data, two memory locations.
>  Sounds like a useful function, though I do not believe it really
>  introduces a "new" feature.
>  Forgive me if I am stating what is obvious to all others.

The thing that is new about it is that it is "standard" (insomuch
as such a representation-specific thing can be).  I can't think of
any F77 compiler that doesn't allow you to play simillar tricks
with equivalence (albeit sometimes a bit buggy when optimized).
This discussion was about what was standard and/or "safe".  I
don't think that really "new" features were implied.

Also, by doing this through an intrinsic function instead of by an
equivalence, the nature of what is going on is much more obvious,
both to the human reader and to the optimizing compiler.
--

Richard Maine
maine@elxsi.dfrf.nasa.gov [130.134.1.1]

amull@Morgan.COM (Andrew P. Mullhaupt) (10/17/89)

> 	If I read the June, 1989 draft F8X correctly, then the
> new TRANSFER intrinsic function (p. 13-51, section 13.13.108)
> will do precisely this.  The syntax is
> 
> 	result = TRANSFER(SOURCE, MOLD, SIZE) .
> 
> It "returns a result with a physical representation identical to that
> of SOURCE but interpreted with the type and type parameters of MOLD."
> The last argument, SIZE, is optional and affects the array shape
> of the result when SOURCE and MOLD have different sizes
> (e.g., double precision and character).
> 
> 
Pardon me for asking, but is this TRANSFER a low level version of the APL
reshape primitive? EQUIVALENCE had this kind of effect, and it seems that
TRANSFER is getting another step closer to a kind of cross between reshape
and take. In previous postings I have advocated adopting the tamer APL
array manipulations in the array extensions for FORTRAN. This is another
case where I believe the various things TRANSFER could get up to should be
split (syntactically) between three different classes, two of which are APL
inspired:

1. Reshaping. This is where the elements retain their values, but a vector
of ten elements can be made into, say, a five by two matrix.

2. Taking. This is where an array of specified size is abstracted from an
existing matrix. For example, the upper left hand two by three matrix can
be taken from a ten by ten matrix. "Overtaking" a larger array from a 
smaller array results (in APL) in filling by zeros.

3. Casting. This is where the data is some floating representation which you
need to interpret as function pointers, (etc.). This use is the one under 
discussion in this thread.

As some have pointed out, being able to cue the compiler, and other programmers
that casting is being done. I find it useful to have a syntactic representation
that distinguishes this from the other applications is helpful.

What is the real semantic interpretation of TRANSFER (Since I don't have time
to go through the Draft proposal, I don't know), and are there other new
facilities for Reshaping, and Taking?

Later,
Andrew Mullhaupt

maine@elxsi.dfrf.nasa.gov (Richard Maine) (10/17/89)

In article <448@e-street.Morgan.COM> amull@Morgan.COM (Andrew P. Mullhaupt) writes:

>  Pardon me for asking, but is this TRANSFER a low level version of the APL
>  reshape primitive? EQUIVALENCE had this kind of effect, and it seems that
>  TRANSFER is getting another step closer to a kind of cross between reshape
>  and take. In previous postings I have advocated adopting the tamer APL
>  array manipulations in the array extensions for FORTRAN. This is another
>  case where I believe the various things TRANSFER could get up to should be
>  split (syntactically) between three different classes, two of which are APL
>  inspired:

>  1. Reshaping. This is where the elements retain their values, but a vector
>  of ten elements can be made into, say, a five by two matrix.

>  2. Taking. This is where an array of specified size is abstracted from an
>  existing matrix. For example, the upper left hand two by three matrix can
>  be taken from a ten by ten matrix. "Overtaking" a larger array from a 
>  smaller array results (in APL) in filling by zeros.

>  3. Casting. This is where the data is some floating representation which you
>  need to interpret as function pointers, (etc.). This use is the one under 
>  discussion in this thread.

>  As some have pointed out, being able to cue the compiler, and other programmers
>  that casting is being done. I find it useful to have a syntactic representation
>  that distinguishes this from the other applications is helpful.

>  What is the real semantic interpretation of TRANSFER (Since I don't have time
>  to go through the Draft proposal, I don't know), and are there other new
>  facilities for Reshaping, and Taking?

TRANSFER is a cast.  The bits of the underlying representation are transferred
without change.  The shaping involved in transfer is not really the main
point; it is needed mostly to handle types of different sizes (as in
transferring a double precision scalar to an array of characters).  True,
you could use TRANSFER just for its reshaping, but that would be a bit
of an "abuse".

There is a separate function just for reshaping, called (strangely enough),
RESHAPE.

Taking sounds mostly like the 8x matrix section.  If A is a 10x10 matrix,
then A(1:2,1:2) is a 2x2 matrix taken from the upper left corner.
However, you cannot extract a larger matrix from a smaller one, other
than by writing it out as in
     REAL A(2,2),B(10,10)
     B = 0
     B(1:2,1:2) = A

--

Richard Maine
maine@elxsi.dfrf.nasa.gov [130.134.1.1]

jjb3281@acf5.NYU.EDU (Thanbo) (10/19/89)

In article <1131@mpx1.lanl.gov>, matthias@mpx1.lanl.gov (Bjorn E. Matthias, M/S H831, 7-6241 or 7-7906) writes:
> > 
> > 	result = TRANSFER(SOURCE, MOLD, SIZE) .
> 
> If I am not mistaken, then this could be previously accomplished in
> VAX FORTRAN with EQUIVALENCE between two variables of whatever types.
> I have used this often and it appears that TRANSFER is different only
> in that one truly has *two* pieces of data, two memory locations.
> Sounds like a useful function, though I do not believe it really

This sort of thing has been done for years.  We do this with a tiny
assembly-language program called MVCX(nbytes, src, dst) which simply
copies so many bytes from src to test.  It's about 12 instructions on
the S/370 machines, or 6 instructions on VAX, with error checks to 
make sure you're passing valid addresses of arguments, and a valid
length (since FORTRAN passes by reference, the function has the addresse
of the arguments available).
                                 Thanbo
                                 Information Builders Inc.
                                 jjb3281@acf5.nyu.edu

hirchert@uxe.cso.uiuc.edu (10/20/89)

Note that FORTRAN is nominally a (semi-)portable language for computation, not
system programming.  In general, if it is not possible to portably predict
the result of an action (or at least a portable framework for those results),
that action is likely to have been prohibited by the standard.  In the case
of type "punning", the result could either be a merely unpredictable value or
a value that would cause the processor to abort (e.g. an IEEE NaN).  Since
standard FORTRAN has no mechanism for handling exceptions, the standard
disallows the use of storage association to do type "punning".  In practice,
FORTRAN compilers rarely, if ever, directly enforce this prohibition.  However,
some optimizers do not see the use of a variable of one type as being
related to the definition of a storage associated variable if the latter
variable is of an unrelated type.  This can make type "punning" by
EQUIVALENCE unreliable.

In the proposed Fortran 8x draft, an explicit intrinsic TRANSFER has been
provided for type "punning".  This provides an optimizer with the connection
between its input value and the output value.  It also serves to warn future
readers that "dangerous" things are being done.  (EQUIVALENCE can be used in
either "safe" or "dangerous" ways.)

A previous post suggested that "punning" by EQUIVALENCE might be more efficient
than by the TRANSFER intrinsic.  If properly implemented, the reverse should
be true.  To do "punning" by EQUIVALENCE, there must be an EQUIVALENCE between
the object containing the input value and an object of the output type.  If
the input value could come from an arbitrary (or at least widely varied)
source, it may not be possible to have every possible source so EQUIVALENCEd,
and it may be necessary to copy the input from its original source to a
variable that has been appropriately EQUIVALENCEd.  TRANSFER, on the other
hand, if implemented as an in-line function, allows the compiler to look at
the input value in a new, wherever it is, and thus should not require copying
in these cases.  (This is in contrast with TRANSFER-like procedures 
implemented as external procedures.  These nearly always require copying and
thus can be expected to be less than either EQUIVALENCE "punning" or an
intrinsic TRANSFER.)

Another post asked about the relation between TRANSFER and various APL
functionalities.  Fortran 8x has separate facilities for reshaping arrays,
so it is not expected TRANSFER would be used for that purpose.  Fortran 8x
has separate facilities for extracting subarrays of an array.  TRANSFER was
intended only for type "punning" or "casting".