[Pyrex] A riddle

Phil Frost indigo at bitglue.com
Tue Apr 18 21:58:33 CEST 2006


On Tue, Apr 18, 2006 at 09:24:05PM +0200, Tomasz Primke wrote:
> Well, I think I have finally find that *.* bug.
> 
> My friend told me, that in C the assumption
> 
>   sizeof( some struct ) == sum of sizeof( all struct's attributes )
> 
> is not always met. The sum of struct's attributes sizes must be rounded up 
> to 4. So I changed the "size" C function code to:
> 
> cdef ULI size( ULI pointers, ULI ulis, ULI usis, ULI ints, ULI doubles ):
>   cdef ULI s
>   s = ... # calculate the sum of all attributes' sizes
>   while s % 4 != 0:
>     s = s + 1
>   return s
> 
> and all works fine now.
> 
> 
> Well, that's what can happen, when a (very) high-level Python man lowers his 
> scope to low-level world of C and memory managment done by PC machines...

This assumption is also not safe. If what you want is the size of some
structure, there is no always safe solution but sizeof(someStructure).
Compilers may insert unused bytes in the middle of a structure to align
members on address that are faster for the target platform, for example.
Consider this structure:

struct foo {
  char a;
  int b;
  char c;
  int d;
  char e;
  int f;
};

On ia32, "char" is 1 byte, and "int" is 4. However, accessesing an int
if it is not on a 4-byte aligned address is much slower. The compiler is
likely to insert 3 bytes of padding after each char member. The sum of
the sizes of the members of this structure is 15 bytes. With padding
added as described, the structure is 24 bytes.

There are compiler specific flags or __attribute__ magics or #pragma
incantations that allow one to control just how a compiler arranges
structures. However, they are the work of the devel, and best avoided.



More information about the Pyrex mailing list