B
Bradford Chamberlain
I work a lot with multidimensional arrays of dynamic size in C,
implementing them using a single-dimensional C array and the
appropriate multipliers and offsets to index into it appropriately. I
tend to iterate over subsets of these arrays by walking a pointer and
an offset per dimension across their dimensions. I've found that this
tends to result in more performance in a portable manner than doing
explicit indexing calculations and hoping that the compiler hoists
invariant expressions out of the loops.
For example, rather than doing something like:
{
for (i=ilo; i<ihi; i+=istr) {
for (j=jlo; j<jhil j+=jstr) {
... a[(i-ailo)*imult + (j-ajlo)*jmult] ...
}
}
}
I would tend to do:
{
double* aptr = ...;
const int abumpj = ...;
const int abumpi = ...;
for (i=ilo; i<ihi; i+=istr) {
for (j=jlo; j<jhil j+=jstr) {
... *aptr ...
aptr += abumpj;
}
aptr += abumpi;
}
}
My question is motivated by the following desire: If I have an array
of structures, I'd like to be able to walk around *a single field*
within the array in a similar manner. For example, given the
structure:
struct _mystruct {
short x;
double y;
char z;
}
I would like the ability to walk through the "y" fields of the array
using a pointer and offsets.
I've been able to achieve this using a char* pointer as follows:
{
char* xptr = ...; /* point to y field of the initial element */
const int xbumpj = ...; /* express in bytes rather than */
const int xbumpi = ...; /* sizeof(doubles) */
for (i=ilo; i<ihi; i+=istr) {
for (j=jlo; j<jhil j+=jstr) {
... *((double*)xptr) ...
xptr += xbumpj;
}
xptr += xbumpi;
}
}
I'd really prefer to eliminate the reliance on char* pointers and
pointer casting, however. In particular, I'd like to make xptr a
double*.
My question is therefore the following: does C have any requirements
on structure layout that would ensure that walking from field to field
within an array of structures will be evenly divisible by sizeof()
that field's type?
If not, it seems like my hope is in vain because the additive offsets
will be in terms of sizeof(<field type>) rather than bytes (or I will
have to cast my pointer back to char* before adding a generic offset
to it).
If so, I'm off and running. However, it's hard for me to believe that
C would ensure such rules on padding, which is why I ask.
The only other approach I can think of is to walk a structure pointer
over my array's elements and then dereference the pointer to access
the field. I guess I've avoided this approach simply due to the fact
that it seems more expensive (due to the field offset calculation
involved).
Does anyone have any other suggstions for how I might write such code
without relying on char* pointers?
Thanks,
-Brad
implementing them using a single-dimensional C array and the
appropriate multipliers and offsets to index into it appropriately. I
tend to iterate over subsets of these arrays by walking a pointer and
an offset per dimension across their dimensions. I've found that this
tends to result in more performance in a portable manner than doing
explicit indexing calculations and hoping that the compiler hoists
invariant expressions out of the loops.
For example, rather than doing something like:
{
for (i=ilo; i<ihi; i+=istr) {
for (j=jlo; j<jhil j+=jstr) {
... a[(i-ailo)*imult + (j-ajlo)*jmult] ...
}
}
}
I would tend to do:
{
double* aptr = ...;
const int abumpj = ...;
const int abumpi = ...;
for (i=ilo; i<ihi; i+=istr) {
for (j=jlo; j<jhil j+=jstr) {
... *aptr ...
aptr += abumpj;
}
aptr += abumpi;
}
}
My question is motivated by the following desire: If I have an array
of structures, I'd like to be able to walk around *a single field*
within the array in a similar manner. For example, given the
structure:
struct _mystruct {
short x;
double y;
char z;
}
I would like the ability to walk through the "y" fields of the array
using a pointer and offsets.
I've been able to achieve this using a char* pointer as follows:
{
char* xptr = ...; /* point to y field of the initial element */
const int xbumpj = ...; /* express in bytes rather than */
const int xbumpi = ...; /* sizeof(doubles) */
for (i=ilo; i<ihi; i+=istr) {
for (j=jlo; j<jhil j+=jstr) {
... *((double*)xptr) ...
xptr += xbumpj;
}
xptr += xbumpi;
}
}
I'd really prefer to eliminate the reliance on char* pointers and
pointer casting, however. In particular, I'd like to make xptr a
double*.
My question is therefore the following: does C have any requirements
on structure layout that would ensure that walking from field to field
within an array of structures will be evenly divisible by sizeof()
that field's type?
If not, it seems like my hope is in vain because the additive offsets
will be in terms of sizeof(<field type>) rather than bytes (or I will
have to cast my pointer back to char* before adding a generic offset
to it).
If so, I'm off and running. However, it's hard for me to believe that
C would ensure such rules on padding, which is why I ask.
The only other approach I can think of is to walk a structure pointer
over my array's elements and then dereference the pointer to access
the field. I guess I've avoided this approach simply due to the fact
that it seems more expensive (due to the field offset calculation
involved).
Does anyone have any other suggstions for how I might write such code
without relying on char* pointers?
Thanks,
-Brad