Re: ISO: help porting C code to 64 bit linux platform



Jan Panteltje <pNaonStpealmtje@xxxxxxxxx> writes:

On a sunny day (Thu, 11 Jan 2007 19:15:24 +0000) it happened
=?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= <mru@xxxxxxxxxxxxx> wrote in
<yw1x64bdjrxv.fsf@xxxxxxxxxxxxxxxxxxxxx>:

The trick to writing portable code is to never assume anything about
the size of types other than the intXX_t family. By using the least
restrictive type that is guaranteed to give correct results, the
compiler is free to do its job optimally.

I think that will get you into trouble.
The first case is the structures used as template for header files.
Look at this I found:

wave_header.h
typedef unsigned short WORD;
typedef unsigned long DWORD;

typedef struct
{ /* header for WAV-Files */
char main_chunk[4]; /* 'RIFF' */
DWORD length; /* length of file */
char chunk_type[4]; /* 'WAVE' */
char sub_chunk[4]; /* 'fmt' */
DWORD length_chunk; /* length sub_chunk, always 16 bytes */
WORD format; /* always 1 = PCM-Code */

WORD modus; /* 1 = Mono, 2 = Stereo */
DWORD sample_fq; /* Sample Freq */
DWORD byte_p_sec; /* Data per sec */
WORD byte_p_spl; /* bytes per sample, 1=8 bit, 2=16 bit (mono)
2=8 bit, 4=16 bit (stereo) */
WORD bit_p_spl; /* bits per sample, 8, 12, 16 */
char data_chunk[4]; /* 'data' */
DWORD data_length; /* length of data */
} wave_header;

If you port this to 64 bits it will fail, because unsigned long
takes more space. So if the code uses anything like

int header_size;
...
in_header[i] = malloc(header_size);
...
a = fread(in_header[i], sizeof(char), header_size, ifptr[i]);
you read the wrong header parameters on a 64 bit system.

That is a good example of how *not* to write code. *Never*, ever read
or write a struct directly to/from a file. The compiler is free to
insert padding wherever it likes in a struct.

--
Måns Rullgård
mru@xxxxxxxxxxxxx
.