A Record Interpretation of an Array
Author Message
A Record Interpretation of an Array

I know what I'm going to be asking about is not defined by the language,
is non-portable, is implementation defined, etc.  I'm just looking to
gather some thoughts and opinions here.

Consider a plain, simple, fixed-length array of some type--no variants,
tagged types, unconstrained anythings, packing pragmas or
specifications.  Just your plain 'ole basic array.  For example, an
array (1..5) of Integer.

If I wanted to access the contents of this array as a analogous record,
I could declare something like:

type Record_View is
record
Field1 : Integer;
Field2 : Integer;
Field3 : Integer;
Field4 : Integer;
Field5 : Integer;
end record;

and do an Unchecked_Conversion between the array type and this record
type.

Is it reasonable to think this conversion (going either way) would give
sensible results?  Is there a stronger basis for that answer than a
naive "reasonable to think"?

What if the array element type was of a record type, whose 'size
indicated an odd number of bytes?  My experience has been that arrays of
such types pad out the elements, and so could one also reasonably expect
the analogous record view to equivalently pad out each such field?

And last, if the array was multi-dimensional (but still statically
constrained), could a record be constructed to correctly overlay that
array?  For example:

type Array_2_X_4 is array (1..2, 1..4) of Some_Type;

type Index_2_Elements is
record
Field1 : Some_Type;
Field2 : Some_Type;
Field3 : Some_Type;
Field4 : Some_Type;
end record;

type Index_1_Elements is
record
Field1 : Index_2_Elements;
Field2 : Index_2_Elements;
end record;

(In case someone asks, "What problem are you actually trying to solve
here?"  The answer is, to manipulate an array via a record-oriented
approach.  I have a lot of code that does varied and sundry things with
record definitions, and by considering an array as a degenerate case of
a record (the fields are all of the same, rather than different, types),
I can reuse that code to do the exact same kinds of things to arrays
that I already do to records.)

Marc A. Criley

Sat, 15 Nov 2003 06:53:17 GMT
A Record Interpretation of an Array

Quote:

> I know what I'm going to be asking about is not defined by the language,
> is non-portable, is implementation defined, etc.  I'm just looking to
> gather some thoughts and opinions here.

> Consider a plain, simple, fixed-length array of some type--no variants,
> tagged types, unconstrained anythings, packing pragmas or
> specifications.  Just your plain 'ole basic array.  For example, an
> array (1..5) of Integer.

> If I wanted to access the contents of this array as a analogous record,
> I could declare something like:

>   type Record_View is
>     record
>       Field1 : Integer;
>       Field2 : Integer;
>       Field3 : Integer;
>       Field4 : Integer;
>       Field5 : Integer;
>     end record;

> and do an Unchecked_Conversion between the array type and this record
> type.

> Is it reasonable to think this conversion (going either way) would give
> sensible results?  Is there a stronger basis for that answer than a
> naive "reasonable to think"?

This is reasonable. I can't see any reason why they would not be
represented internally the same way. If you're willing to add some
representation information to the record type, you could probably check
this (for Record_View'Size use Array_Type'Size;). If you can also put
some representation information on the array type you can ensure this.

Quote:

> What if the array element type was of a record type, whose 'size
> indicated an odd number of bytes?  My experience has been that arrays of
> such types pad out the elements, and so could one also reasonably expect
> the analogous record view to equivalently pad out each such field?

Here you're getting onto thinner ice. It would be better to require
identical representations here. Even if you can't add representation
clauses to the array, you could still add them to a derived type:

type Array_With_Representation is new Array_Type;
for Array_With_Representation'Component_Size use ...;
pragma Pack (Array_With_Representation);
for Array_With_Representation'Size use ...;

Lay out your Record_View type to use the same representation, then
convert your array value to Array_With_Representation before unchecked
converting it Record_View:

To_Record_View (Array_With_Representation (Array_Value) );

Multidimensional arrays are just a further wrinkle to this idea.

--
Jeff Carter
"I blow my nose on you."
Monty python & the Holy Grail

Sat, 15 Nov 2003 11:29:18 GMT
A Record Interpretation of an Array

Quote:
>Is it reasonable to think this conversion (going either way) would give
>sensible results?  Is there a stronger basis for that answer than a
>naive "reasonable to think"?

In my book it is Wrong (with a capital 'W') to ever depend on the size and/or
representation of a type without explicitly specifying it using the appropriate
rep clauses.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html

Sat, 15 Nov 2003 21:34:03 GMT
A Record Interpretation of an Array
You might want to consider that an Ada implementation might keep dope
information about the array in the same vicinity and that this information
may not be required by the record. Size & index range info could be kept at
the beginning of the array (for runtime checks - although it would likely be
at a negative offset from the start of the array so that My_Array'Address
yields the first element of the array). The dope information might be
considered as part of the array for purposes of assignment. The record type
wouldn't need the same info, so it is conceivable in my mind that an
unchecked conversion between the two wouldn't work.

Obviously, as your disclaimer indicates, this is all going to be extremely
implementation dependent and it wouldn't be advisable to rely on such a
thing working - especially without representation clauses.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution

Web:      http://www.mcondic.com/

Quote:

> I know what I'm going to be asking about is not defined by the language,
> is non-portable, is implementation defined, etc.  I'm just looking to
> gather some thoughts and opinions here.

> Consider a plain, simple, fixed-length array of some type--no variants,
> tagged types, unconstrained anythings, packing pragmas or
> specifications.  Just your plain 'ole basic array.  For example, an
> array (1..5) of Integer.

> If I wanted to access the contents of this array as a analogous record,
> I could declare something like:

>   type Record_View is
>     record
>       Field1 : Integer;
>       Field2 : Integer;
>       Field3 : Integer;
>       Field4 : Integer;
>       Field5 : Integer;
>     end record;

> and do an Unchecked_Conversion between the array type and this record
> type.

> Is it reasonable to think this conversion (going either way) would give
> sensible results?  Is there a stronger basis for that answer than a
> naive "reasonable to think"?

> What if the array element type was of a record type, whose 'size
> indicated an odd number of bytes?  My experience has been that arrays of
> such types pad out the elements, and so could one also reasonably expect
> the analogous record view to equivalently pad out each such field?

> And last, if the array was multi-dimensional (but still statically
> constrained), could a record be constructed to correctly overlay that
> array?  For example:

>   type Array_2_X_4 is array (1..2, 1..4) of Some_Type;

>   type Index_2_Elements is
>     record
>       Field1 : Some_Type;
>       Field2 : Some_Type;
>       Field3 : Some_Type;
>       Field4 : Some_Type;
>     end record;

>   type Index_1_Elements is
>     record
>       Field1 : Index_2_Elements;
>       Field2 : Index_2_Elements;
>     end record;

> (In case someone asks, "What problem are you actually trying to solve
> here?"  The answer is, to manipulate an array via a record-oriented
> approach.  I have a lot of code that does varied and sundry things with
> record definitions, and by considering an array as a degenerate case of
> a record (the fields are all of the same, rather than different, types),
> I can reuse that code to do the exact same kinds of things to arrays
> that I already do to records.)

> Marc A. Criley

Sat, 15 Nov 2003 22:16:19 GMT
A Record Interpretation of an Array

Quote:

> I know what I'm going to be asking about is not defined by the language,
> is non-portable, is implementation defined, etc.  I'm just looking to
> gather some thoughts and opinions here.

> Consider a plain, simple, fixed-length array of some type--no variants,
> tagged types, unconstrained anythings, packing pragmas or
> specifications.  Just your plain 'ole basic array.  For example, an
> array (1..5) of Integer.

> If I wanted to access the contents of this array as a analogous record,
> I could declare something like:

>   type Record_View is
>     record
>       Field1 : Integer;
>       Field2 : Integer;
>       Field3 : Integer;
>       Field4 : Integer;
>       Field5 : Integer;
>     end record;

> and do an Unchecked_Conversion between the array type and this record
> type.

> Is it reasonable to think this conversion (going either way) would give
> sensible results?  Is there a stronger basis for that answer than a
> naive "reasonable to think"?

This will often work, but it's not guaranteed.  In fact, I know of an
that would reorder record components, even if they're all of the same
type.  It normally reordered record components to minimize gaps; for
example, it would try to put components with stricter alignment
requirements first.  In the initial implementation, it used an
unstable sort (one that would not maintain the original ordering for
elements with equal keys -- I think it was a straight Quicksort), so
your Record_View might be ordered something like Field3, Field5,
Field2, Field4, Field1.

It's quite possible that no current implementation does this.  If you
decide to depend on that, I suggest that the first thing your code
should do is test whether things are laid out as you expect them to
be, and raise a fatal exception if they aren't.

You might have a better chance of getting away with it if you use
something like "pragma Convention(C, Record_View);".

Of course the most reliable way is to completely specify the layout
yourself, but then you're overriding the compiler's knowledge of what
layout is most efficient.

--

San Diego Supercomputer Center           <*>  <http://www.sdsc.edu/~kst>
Cxiuj via bazo apartenas ni.

Mon, 17 Nov 2003 08:55:57 GMT
A Record Interpretation of an Array

Quote:

> > If I wanted to access the contents of this array as a analogous record,
> > I could declare something like:

> >   type Record_View is
> >     record
> >       Field1 : Integer;
> >       Field2 : Integer;
> >       Field3 : Integer;
> >       Field4 : Integer;
> >       Field5 : Integer;
> >     end record;

> > and do an Unchecked_Conversion between the array type and this record
> > type.

> > Is it reasonable to think this conversion (going either way) would give
> > sensible results?  Is there a stronger basis for that answer than a
> > naive "reasonable to think"?

> This will often work, but it's not guaranteed.  In fact, I know of an
> that would reorder record components, even if they're all of the same
> type.  It normally reordered record components to minimize gaps; for
> example, it would try to put components with stricter alignment
> requirements first.  In the initial implementation, it used an
> unstable sort (one that would not maintain the original ordering for
> elements with equal keys -- I think it was a straight Quicksort), so
> your Record_View might be ordered something like Field3, Field5,
> Field2, Field4, Field1.

Since all the array elements/record fields in this pathology are of the
same type (therefore size), there should be no reason for a modern
compiler to reorder them.

Quote:
> You might have a better chance of getting away with it if you use
> something like "pragma Convention(C, Record_View);".

That can't hurt...

Quote:
> Of course the most reliable way is to completely specify the layout
> yourself, but then you're overriding the compiler's knowledge of what
> layout is most efficient.

I can't touch the original array declaration, but via ASIS I've got
Utilizing that I can build and constrain the corresponding record's
character.

Marc

Mon, 17 Nov 2003 20:47:23 GMT
A Record Interpretation of an Array

Quote:

> (In case someone asks, "What problem are you actually trying to solve
> here?"  The answer is, to manipulate an array via a record-oriented
> approach.  I have a lot of code that does varied and sundry things with
> record definitions, and by considering an array as a degenerate case of
> a record (the fields are all of the same, rather than different, types),
> I can reuse that code to do the exact same kinds of things to arrays
> that I already do to records.)

OK, then it seems like what you Really Want To Do :-) is to decouple your
algorithms from data representations.  This can be done in very lightweight
ways, and the result is something that is absolutely clear in its intent and
does not depend upon any unchecked programming or other monkey business.

The idea is "abstract, then fulfill the abstractions" as opposed to "pretend
it's something else that is equivalent."

How about an example?  Can you put up some code for some of the "varied and
sundry things" that you would like to be able to reuse, and then we can see
how that might be rewritten to be reusable?(The coercion approach seems like
an attempt to reuse stuff that was not written to be reusable in the first
place).

Mark Lundquist

Tue, 18 Nov 2003 08:14:25 GMT
A Record Interpretation of an Array

[...]

Quote:
> Since all the array elements/record fields in this pathology are of the
> same type (therefore size), there should be no reason for a modern
> compiler to reorder them.

Probably true, but there's no guarantee that it won't.  (I'm probably
more fanatical than most about sticking to what the standard actually
guarantees whenever possible.)

--

San Diego Supercomputer Center           <*>  <http://www.sdsc.edu/~kst>
Cxiuj via bazo apartenas ni.

Tue, 18 Nov 2003 09:22:51 GMT
A Record Interpretation of an Array

Quote:
> The idea is "abstract, then fulfill the abstractions" as opposed to
"pretend
> it's something else that is equivalent."

Yes. That's also the approach I'd use. But notice that there is going to be
overhead. Perhpas small enough not to matter, and perhaps it is going to be
possible to reduce it even more by inlining. But abstracting usually means
procedure calls.

--

http://purl.oclc.org/NET/ehudlamm <==  Me!

Tue, 18 Nov 2003 16:45:11 GMT
A Record Interpretation of an Array

Quote:

> > (In case someone asks, "What problem are you actually trying to solve
> > here?"  The answer is, to manipulate an array via a record-oriented
> > approach.  I have a lot of code that does varied and sundry things with
> > record definitions, and by considering an array as a degenerate case of
> > a record (the fields are all of the same, rather than different, types),
> > I can reuse that code to do the exact same kinds of things to arrays
> > that I already do to records.)

> OK, then it seems like what you Really Want To Do :-) is to decouple your
> algorithms from data representations.  This can be done in very lightweight
> ways, and the result is something that is absolutely clear in its intent and
> does not depend upon any unchecked programming or other monkey business.

> The idea is "abstract, then fulfill the abstractions" as opposed to "pretend
> it's something else that is equivalent."

> How about an example?  Can you put up some code for some of the "varied and
> sundry things" that you would like to be able to reuse, and then we can see
> how that might be rewritten to be reusable?(The coercion approach seems like
> an attempt to reuse stuff that was not written to be reusable in the first
> place).

I know what you're saying here, and in 99+% of applications the
decoupling and abstraction would be done just as you describe.

What I've got here, though, is a low-level debugging aid that directly
manipulates raw byte streams, and is therefore intimately concerned with
the layout of data, whether it be scalars, records, or arrays.

In a sense, a "record" _is_ an abstraction of the byte stream (step away
for a moment from the concept of a physical Ada record--to the idea of a
record as an abstract collection of information).  I have software that
interprets the contents of the byte stream as this kind of abstract
record, which of course maps well to the bytes associated with a
physical record.  So the question then concerns the reasonableness of
mapping a physical Ada array to this same abstract record--with the
record fields representing array elements.

Marc

Tue, 18 Nov 2003 20:39:48 GMT
A Record Interpretation of an Array

Quote:

> ...
> What I've got here, though, is a low-level debugging aid that directly
> manipulates raw byte streams, and is therefore intimately concerned with
> the layout of data, whether it be scalars, records, or arrays.
> ...
>  So the question then concerns the reasonableness of
> mapping a physical Ada array to this same abstract record--with the
> record fields representing array elements.

I would say not bother using a record, but instead consider
using an array indexed by an enumeration type, where the
enumeration literals correspond to the names of the
record fields.

Quote:

> Marc

--

Chief Technology Officer, AverCom Corporation (A Titan Company)
Burlington, MA  USA (AverCom was formerly the Commercial Division of AverStar:
http://www.averstar.com/~stt)

Wed, 19 Nov 2003 02:20:36 GMT

 Page 1 of 1 [ 11 post ]

Relevant Pages