Type punning in C 
Author Message
 Type punning in C


< >
< >Why not use equivalence?
< >       INTEGER I
< >       REAL X, IX
< >       EQUIVALENCE (X,IX)
< >
< >       IX = I
< >The fortran standard specifies that a REAL and INTEGER occupy the same space.
< >The only problem is this might fool some optimizers.
< >

Quote:
> Problem is, the Fortran standard *also* says that if your program tries
> to take the value of the variable using a different type than the type you
> used when you last stored into it, your program is invalid.  This is a
> polite way of saying (to the user) 'this trick may not work', and (to the
> compiler writer) 'your optimizer does not have to worry about aliasing
> between variables of different types'.  If the compiler can tell that
> you are going to (e.g.) store an integer into that storage, and then
> read a real, it is under no obligation to make sure that the integer
> value gets stored.

> Fortran equivalence was designed toallow reuse of storage on the early
> small memory machines -- not to allow type punning.  Usually you can
> get away with punning, but it doesn't always work and so is a bad habit.

This is another example of those "gurus" who can not envision an intelligent
user using the machine in an intelligent manner, and prevent that use.  I
have deliberately used "type punning" on various machines, and I consider it
an extremely useful tool.  Now, I do not mind the compiler asking me if I
really wanted to do it, but I object to anyone telling me that I CAN NOT
use instructions that do what I want to do.

It should not even bother an optimizer.  The optimizer takes the operations
given by the programmer, in some cases applies transformations known to
provide the same result, and optimizes the order.  Why should an integer
and a floating point number in the same location bother it, unless that
location is a register and the (expletives deleted) hardware has different
integer and floating registers?  But even that should not befuddle the
optimizer.

Quote:
> --



>  (Phone: +44 272 303132) |     UUCP: ...!mcvax!ukc!gdr.bath.ac.uk!exspes

--
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054



Fri, 19 Mar 1993 12:21:00 GMT  
 Type punning in C

Quote:



>< >Why not use equivalence?

 [several lines deleted]

Quote:
>> Problem is, the Fortran standard *also* says that if your program tries...

 [several lines deleted]

Quote:
>This is another example of those "gurus" who can not envision an intelligent
>user using the machine in an intelligent manner, and prevent that use.  I
>have deliberately used "type punning" on various machines, and I consider it
>an extremely useful tool.....

 [several lines deleted]

I agree wholeheartedly.  FORTRAN doesn't have PL/1's UNSPEC verb, yet
I have had occasion to want it.  And EQUIVALENCE provided it.
Calling a subroutine with "wrong" type parameters can also work:
   CALL NEWTYP (INTEGER,...)
       :::::
   SUBROUTINE NEWTYP (REAL,...)
--Myron
--
Myron A. Calhoun, PhD EE, W0PBV, (913) 532-6350 (work), 539-4448 (home).


UUCP:  ...{rutgers, texbell}!ksuvax1!harry!mac



Fri, 19 Mar 1993 13:10:00 GMT  
 Type punning in C

Quote:

> ... [discussion about type punning and equivalence]
>  It should not even bother an optimizer.  The optimizer takes the operations
>  given by the programmer, in some cases applies transformations known to
>  provide the same result, and optimizes the order.  Why should an integer
>  and a floating point number in the same location bother it, unless that
>  location is a register and the (expletives deleted) hardware has different
>  integer and floating registers?  But even that should not befuddle the
>  optimizer.

Well, you partially answered your own question.  The optimizers often
play register allocation games and this can certainly interfere with
that.  Do recall that the Fortran standard is intended to apply to
many varieties of hardware, including some that deserve the deleted
expletives.

Actually, even perfectly standard equivalences involving no type
punning can and often do mess up optimizers.  The optimizer just
"forgets" to account for the possibility of variable references
or definitions through the equivalence.  This is far from a trivial
issue.  Ok, it may not be a "good" reason, and you can {*filter*} about
the sloppy compiler all you want (I do), but I guarantee its a real
reason.  I have seen many instances of such bugs in many compilers
(usually when helping other people debug their programs).

I try to avoid equivalence and its ilk as much as possible, both
for the usual clarity/style reasons and to lessen my exposure to
this class of compiler bugs.  Of course, "as much as possible"
doesn't mean always.  I'm guilty.  I've done it and will undoubtedly
do it again.  BUt I do regret it every time.

--

Richard Maine



Fri, 19 Mar 1993 16:17:00 GMT  
 Type punning in C

Quote:



>< >
>< >Why not use equivalence?
>< >   INTEGER I
>< >   REAL X, IX
>< >   EQUIVALENCE (X,IX)
>< >
>< >The Fortran standard specifies that a REAL and INTEGER occupy the same space.
>> Fortran equivalence was designed toallow reuse of storage on the early
>> small memory machines -- not to allow type punning.  Usually you can
>> get away with punning, but it doesn't always work and so is a bad habit.

>This is another example of those "gurus" who can not envision an intelligent
>user using the machine in an intelligent manner, and prevent that use.  I
>have deliberately used "type punning" on various machines, and I consider it
>an extremely useful tool.  Now, I do not mind the compiler asking me if I
>really wanted to do it, but I object to anyone telling me that I CAN NOT
>use instructions that do what I want to do.

Trust me, 'cause I don't want to get into a long discussion of FORTRAN
in a C newsgroup.  There are an incredible number of things which may
cause aliasing in FORTRAN, some of it invisible to the compiler at any
given moment due to separate compilation of modules, and so the
optimizer needs all the help it can get.  '77 FORTRAN is even more
restrictive on the user as regards possible punning and aliasing than
'66 FORTRAN was, in order primarily to permit more reliable optimization.

The need for a construct to permit type punning is clear, particularly
if you're doing 'systemmy' work.  People working on the Algol compiler
on Multics (which does even more stringent, and cross-module, type
checking) resorted to writing little PL/1 routines which simply took
whatever they were given and passed it straight back,
unchanged(bitwise) -- and declared them in the Algol code as 'foreign'
('other language module, suspend type checking') 'takes integer returns
real'.  Lies, in other words.

I tend to like things which match PL/1's 'unspec' in concept.  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...)

--



 (Phone: +44 272 303132) |     UUCP: ...!mcvax!ukc!gdr.bath.ac.uk!exspes



Fri, 19 Mar 1993 09:03:00 GMT  
 Type punning in C

Quote:
(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).

--------
        Peter Montgomery



Fri, 19 Mar 1993 03:25:00 GMT  
 Type punning in C

Quote:


> (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




Fri, 19 Mar 1993 19:18:00 GMT  
 Type punning in C

Quote:
>> [.. 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



Fri, 19 Mar 1993 15:59:00 GMT  
 Type punning in C
Quote:
>    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



Fri, 19 Mar 1993 18:32:00 GMT  
 Type punning in C

Quote:
>  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



Fri, 19 Mar 1993 14:52:00 GMT  
 Type punning in C

Quote:

> >       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.



Fri, 19 Mar 1993 23:59:00 GMT  
 Type punning in C

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".



Fri, 19 Mar 1993 16:36:00 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. to CS: or not to CS: in F-PC assembler

2. Ruby Newbie (pun not intended)

3. French pun on Python! :-)

4. Hi all - new to smalltalk [type services and type-safety]

5. statically Typed vs dinamically typed

6. Strongly Typed and Weakly Typed Languages

7. Difference between a type system and a type constraint system

8. The notions of type and of type constraint

9. Types, types: static vs. dynamic -- classification

10. Types, types: static vs. dynamic --

 

 
Powered by phpBB® Forum Software