Here's a program:
#include <stdio.h>
int main(int argc, char **argv)
{
double an_array[] = {0.0, 1.0, 2.0, 3.0, 4.0};
typedef struct a_struct {double v0, v1, v2,v3, v4;} a_type;
typedef a_type *a_type_ptr;
a_type_ptr s_ptr;
s_ptr = (a_type_ptr) an_array;
printf( "%8.5f %8.5f %8.5f %8.5f %8.5f\n",
s_ptr -> v0,
s_ptr -> v1,
s_ptr -> v2,
s_ptr -> v3,
s_ptr -> v4 );
}
Using a recent gcc, this prints out the elements of the array
correctly, i.e.
0.00000 1.00000 2.00000 3.00000 4.00000
For what versions (if any) of standard C is this kluge required to
work? (same alignment and offsets for array items and struct members of
the same type).
TIA
Al
In summary, you are trying to access a structure:
struct MyStruct
{
double v0;
double v1;
/* ... */
double v4;
};
as an array.
There is what I call the Structure Size Rule for C and C++:
"The size of a structure _may_ not be equal to the sum of
the size of its members."
This rule comes about because a compiler is allowed to
add "padding" elements after each member or field of a
structure. The compiler may want to add the padding to
make the fields easier or more convenient for the processor
to access.
Let us say we have a processor that likes to retrieve
32 bit quantities, known as a fetch. Let us also say
that the processor has an 8-bit char, 16-bit short int
and a 32-bit int (unsigned have the same sizes). When
the processor needs to fetch any of these quantities,
it fetches 32 bits at a time and discards the rest.
Given the following structure:
struct Example
{
char a;
short int b;
int c;
};
The member 'a' is 8-bits wide. The processor wants to
fetch 32 bits. Without any padding the process will
fetch 8 bits of 'a', 16 more bits of 'b' and finally
8 bits of 'c'. It will discard the unused bits, which
in this case, is no problem.
The member 'b' is 16-bits wide, but not at the first
fetch. The processor must fetch from the location
of the first member, remove the extraneous bits
then shift the remaining 16 bits to the correct
position. If we added 24 bits (32 bits - 8 bits
of char) of padding between 'a' and 'b', then the
fetching of 'b' would have no extraneous bits and
no shifting to take place -- more efficient.
The process of adding padding space is called
"alignment". Alignment allows processors to fetch
data more efficiently. However, adding padding
changes the size and layout of a structure. One
cannot map the members of a structure to a real
world structure because of the Structure Size Rule.
Packed Structures
-----------------
Some compilers have #pragmas that allow "packing"
of structures. The term "packing" referes to the
elimination of padding after members. This is not
a standard C facility. Also, many compilers may
allow packed structures but have problems accessing
data from them correctly.
Converting to Structures
------------------------
The best process for handling real world data structures
is to treat them as a sequence of "bytes" and extract
and build the data yourself. This technique also allows
one to handle Endianism (the ordering of "bytes" for
multi-byte units). Once the structure is filled,
it can then be accessed without any worries. The
opposite should be followed when creating a sequence
of bytes from a structure.
--
Thomas Matthews
C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq:
http://www.parashift.com/c++-faq-lite
C Faq:
http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book