After doing some more googling, and looking more closely at the DL source,
it appears that DL uses a variant of the trick described at
http://www.monkeyspeak.com/alignment/ to make sure it aligns things as the
platform normally does. Specifically, there’s this code in dl.h:
typedef struct { char c; void *x; } s_voidp;
typedef struct { char c; short x; } s_short;
typedef struct { char c; int x; } s_int;
typedef struct { char c; long x; } s_long;
typedef struct { char c; float x; } s_float;
typedef struct { char c; double x; } s_double;
#define ALIGN_VOIDP (sizeof(s_voidp) - sizeof(void *))
#define ALIGN_SHORT (sizeof(s_short) - sizeof(short))
#define ALIGN_INT (sizeof(s_int) - sizeof(int))
#define ALIGN_LONG (sizeof(s_long) - sizeof(long))
#define ALIGN_FLOAT (sizeof(s_float) - sizeof(float))
#define ALIGN_DOUBLE (sizeof(s_double) - sizeof(double))
I haven’t yet found anything indicating that a struct may be aligned on any
criteria other than its contents, but that doesn’t mean a whole lot. But
even if it does do that, couldn’t you just add a check as above to see?
typedef struct {} struct_type;
typedef struct { char c; struct_type x; } s_struct;
#define ALIGN_STRUCT (sizeof(s_struct) - sizeof(struct_type))
Anyhow, I’d love to see something in writing indicating that a struct may be
aligned differently than it’s contents demand. As far as I can tell,
alignment is done for the benefit of the underlying machine’s access to the
data, and since the underlying machine doesn’t access a struct directly, it
doesn’t really care how it’s aligned, other than to demand that it can
access it’s members correctly. Thus it seems that:
typedef struct { int i; } inner;
typedef struct { char c; inner in; } outer;
Will always be the same as:
typedef struct { char c; int i; } s;
This is definitely expanding my knowledge of C fundamentals… as well as
making me appreciate that Ruby manages to compile in so many different
places.
Nathaniel
<:((><
···
Tim Hunter [mailto:Tim.Hunter@sas.com] wrote:
You can’t assume that “f” in OUTER2 is the same as “inner.a”
in OUTER1. The compiler is free to align structure members,
including “inner”, any way it wants to, and the alignment
requirements for “f” are certainly not the same as for
“inner”. If the compiler chooses, for example, to always
align structures at dword boundaries, then there will be a
word-sized gap between ‘e’ and ‘inner.a’ in the OUTER1 struct
(assuming 32-bit machines) that may not appear between “e”
and “f” in the OUTER2 struct.