[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Calling fun taking struct and not pointer to struct?

Nathaniel Talbott

9/10/2003 11:55:00 PM

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.

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

<:((><


2 Answers

Tim Hunter

9/11/2003 12:18:00 AM

0

On Thu, 11 Sep 2003 08:55:14 +0900, Nathaniel Talbott wrote:

> 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.
>
> 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/... 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
>
> <:((><

A compiler is free to align a structure on a boundary that is stricter
than that required by its members. For example, a structure with an int as
its first member may be aligned on a dword boundary, if that makes it
easier to generate code for accessing the structure elements. (Consider
the needs of arrays of structures allocated from the heap.)

Also a compiler is free to add padding between structure elements as it
sees fit.

For "something in writing" check the ANSI standard.

The reason Ruby compiles on so many different machines is (in part)
because the Ruby authors didn''t depend on non-standard behavior from the
compiler.

Steven Jenkins

9/11/2003 3:26:00 AM

0

Tim Hunter wrote:
> A compiler is free to align a structure on a boundary that is stricter
> than that required by its members. For example, a structure with an int as
> its first member may be aligned on a dword boundary, if that makes it
> easier to generate code for accessing the structure elements. (Consider
> the needs of arrays of structures allocated from the heap.)

Correct. ISO C further guarantees that a pointer to a structure may be
coerced to a pointer to its first element.

> Also a compiler is free to add padding between structure elements as it
> sees fit.

Correct. By the above guarantee, no padding can occur before the first
element.

> For "something in writing" check the ANSI standard.

For the pedantically-inclined, ISO/IEC 9899. But K&R 2nd edition deals
with this adequately in Appendix A.

Steve