Struct on on x86_64 mac os x

Dave Angel davea at ieee.org
Wed Oct 21 07:54:41 EDT 2009


Mark Dickinson wrote:
> On Oct 20, 10:51 pm, Tommy Grav <tg... at pha.jhu.edu> wrote:
>   
>> I have created a binary file that saves this struct from some C code:
>>
>>    struct recOneData {
>>           char label[3][84];
>>           char constName[400][6];
>>         double timeData[3];
>>       long int numConst;
>>         double AU;
>>         double EMRAT;
>>       long int coeffPtr[12][3];
>>       long int DENUM;
>>       long int libratPtr[3];
>>       };
>>
>> I try to read this file with python (ActiveState 2.6.3 on x86_64 Mac  
>> OS X 10.6.1) using the
>> code below the hdrData and constNData are fine, while from the  
>> timeData onwards there
>> are obvious problems. The code below works fine for a 32bit binary  
>> read with i386 python
>> 2.5.2. Does anyone know what the proper format of a C double and long  
>> int is for a x86_64
>> binary?
>>     
>
> As others have said, it depends on the platform.  But on OS X 10.6,
> and on most 64-bit Linuxes that I've met, I'm fairly sure that
> sizeof(long int) =sizeof(double) == 8.  In contrast, 64-bit
> Windows on the same hardware will probably have sizeof(long int) =4.
>
>   
>>      def read_header(cls):
>>          hdrData =84s"*3
>>          constNData =6s"*400
>>     
>
> I'm confused:  why is this not "400s"*6 rather than "6s"*400?
> Doesn't constName[400][6] mean 6 lots of constName[400]?
> Similarly for "84s"*3.  This might be making a difference to
> the padding.
>
> [...]
>
> --
> Mark
>
>   
I don't know much about the 64 bit Unix platforms, since 64bits was just 
a dream last time I used Unix.

But I'd guess that your problem is that double will be aligned to 8 
bytes on some platforms.  Since your characters don't add up to a 
multiple of 8, you'd have some paddding between them.


When you get to define your own file format, the old advice was to:
   1) use text form if possible, where the endianness and the alignment 
are non-issues.
   2) If you must use binary data, directly stored, then put the 
largest-aligned items at the beginning of the struct, and work down to 
the smallest alignments.  That way there is never any padding, except at 
the end of the struct.  For that, add a dummy character field of a size 
appropriate to bring the size to a multiple of the largest alignment, 
generally 8.   You'd still have to worry about endianness, but at least 
padding goes away.

Incidentally, though it doesn't affect the padding issues, I believe you 
have the meaning of constName[400][6] backwards.  This refers to 400 
strings of 6 bytes each.  In C, the definitions are in row-major order.

DaveA




More information about the Python-list mailing list