ISO: help porting C code to 64 bit linux platform - Linux

This is a discussion on ISO: help porting C code to 64 bit linux platform - Linux ; Måns Rullgård writes: > Emmanuel Fleury writes: > >> Måns Rullgård wrote: >>> >>> 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 ...

+ Reply to Thread
Page 2 of 3 FirstFirst 1 2 3 LastLast
Results 21 to 40 of 42

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

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

    Måns Rullgård writes:

    > Emmanuel Fleury writes:
    >
    >> Måns Rullgård wrote:
    >>>
    >>> 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.

    >>
    >> Somehow, I feel you are both right... but you didn't set properly your
    >> initial conditions.
    >>
    >> I think that this is true to FORCE variables size when the data are
    >> coming from outside the program. Typically, in the example of Julián the
    >> struct describe the structure of a wav file which should be played on
    >> any type of machine. This is clearly some data imported from outside the
    >> software and on which the programmer has no control.

    >
    > The WAV header has a number of fixed-size fields, that is true.
    > However, that does not imply that the variables used to hold these
    > values inside a program need to have the same size. They need to be
    > at least as wide, but it doesn't hurt if they are wider if that makes
    > for more efficient code.
    >
    > The correct way to handle things like a WAV header is to read one
    > value at a time, convert it to the machine endianness (the WAV header


    The values are packed in the file?

    > is always little endiean). Reading the header directly into a struct
    > can lead to unpleasant surprises if the compiler inserted padding you
    > didn't expect, and you still need to handle endian conversions.


    What is the best way? use a char* and cast it to the field in question?
    >
    >> On the other hand, Måns is right for all the variables which are lying
    >> within the program. It should be define as a coherent data flow without
    >> relying on the size of it.
    >>
    >> At last, variables which are exported outside of the software must also
    >> have a known size ('cause they will be imported at some other point).

    >
    > Any data going into or out of a program must of course have a defined
    > format. Now this format need only exist at the external interface.
    > In most situations it is preferable to immediately convert input into
    > some more efficient internal format, and convert back on output.


    --

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

    Jan Panteltje writes:

    > On a sunny day (Sat, 13 Jan 2007 11:58:03 +0000) it happened
    > =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    > :
    >
    >>Jan Panteltje writes:
    >>
    >>> On a sunny day (Fri, 12 Jan 2007 19:25:08 +0000) it happened
    >>> =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    >>> :
    >>>
    >>>>Emmanuel Fleury writes:
    >>>>
    >>>>> Mns Rullgrd wrote:
    >>>>>>
    >>>>>> 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.
    >>>
    >>> I have to still see that happen in gcc, do you have a code example?

    >>
    >>#include
    >>#include
    >>#include
    >>
    >>struct pad {
    >> uint16_t foo;
    >> uint32_t bar;
    >>};
    >>
    >>int main(int argc, char **argv)
    >>{
    >> printf("%d %d\n", offsetof(struct pad, foo), offsetof(struct pad, bar));
    >> return 0;
    >>}
    >>
    >>$ gcc foo.c
    >>$ ./a.out
    >>0 4
    >>
    >>See the 2 bytes of padding?

    >
    > OK, I see it, I ran some more tests on code I wrote, maye have to do
    > some re-writing.
    > The fun thing is, some has been out there, and been downloaded a
    > thousand times, and confirmed OK on 32 and 64 bits....
    > I am now trying to see why (I think I was lucky :-) ).
    > mm I found why I think, yes, interesting, variables overlap and it
    > works because 2 zeros then overlap... because of and even number of
    > 16 bit vars in pairs :-)!!


    Yes, if all struct members are aligned at their natural alignment
    without padding, the compiler doesn't usually change anything. That
    doesn't mean that it never will, though, so never depend on it.

    [ctype.h]
    >>I fail to see the relevance of this to the current discussion.

    >
    > The discussion was about 32 bits to 64 bits.
    > The more bits the more bloat this example is.
    > int as return (where a bool is used),
    > and int as argument (where a 8 bits char is used).


    An int takes no more space than a char in a register. When arguments
    are passed on the stack, they are still typically aligned on word
    boundaries, so there would be no savings there either.

    --
    Mns Rullgrd
    mru@inprovide.com

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

    Hadron writes:

    > Mns Rullgrd writes:
    >
    >> Emmanuel Fleury writes:
    >>
    >>> Mns Rullgrd wrote:
    >>>>
    >>>> 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.
    >>>
    >>> Somehow, I feel you are both right... but you didn't set properly your
    >>> initial conditions.
    >>>
    >>> I think that this is true to FORCE variables size when the data are
    >>> coming from outside the program. Typically, in the example of Julin the
    >>> struct describe the structure of a wav file which should be played on
    >>> any type of machine. This is clearly some data imported from outside the
    >>> software and on which the programmer has no control.

    >>
    >> The WAV header has a number of fixed-size fields, that is true.
    >> However, that does not imply that the variables used to hold these
    >> values inside a program need to have the same size. They need to be
    >> at least as wide, but it doesn't hurt if they are wider if that makes
    >> for more efficient code.
    >>
    >> The correct way to handle things like a WAV header is to read one
    >> value at a time, convert it to the machine endianness (the WAV header

    >
    > The values are packed in the file?


    The WAV header happens to be ordered such that all fields have natural
    alignment, but I'm sure that's purely a coincidence.

    >> is always little endiean). Reading the header directly into a struct
    >> can lead to unpleasant surprises if the compiler inserted padding you
    >> didn't expect, and you still need to handle endian conversions.

    >
    > What is the best way? use a char* and cast it to the field in question?


    No, that will give you alignment issues. The safe way is to piece the
    value together one byte at a time using shift and bitwise or
    operations.

    --
    Mns Rullgrd
    mru@inprovide.com

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

    Måns Rullgård writes:

    > Hadron writes:
    >
    >> Måns Rullgård writes:
    >>
    >>> Emmanuel Fleury writes:
    >>>
    >>>> Måns Rullgård wrote:
    >>>>>
    >>>>> 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.
    >>>>
    >>>> Somehow, I feel you are both right... but you didn't set properly your
    >>>> initial conditions.
    >>>>
    >>>> I think that this is true to FORCE variables size when the data are
    >>>> coming from outside the program. Typically, in the example of Julián the
    >>>> struct describe the structure of a wav file which should be played on
    >>>> any type of machine. This is clearly some data imported from outside the
    >>>> software and on which the programmer has no control.
    >>>
    >>> The WAV header has a number of fixed-size fields, that is true.
    >>> However, that does not imply that the variables used to hold these
    >>> values inside a program need to have the same size. They need to be
    >>> at least as wide, but it doesn't hurt if they are wider if that makes
    >>> for more efficient code.
    >>>
    >>> The correct way to handle things like a WAV header is to read one
    >>> value at a time, convert it to the machine endianness (the WAV header

    >>
    >> The values are packed in the file?

    >
    > The WAV header happens to be ordered such that all fields have natural
    > alignment, but I'm sure that's purely a coincidence.
    >
    >>> is always little endiean). Reading the header directly into a struct
    >>> can lead to unpleasant surprises if the compiler inserted padding you
    >>> didn't expect, and you still need to handle endian conversions.

    >>
    >> What is the best way? use a char* and cast it to the field in question?

    >
    > No, that will give you alignment issues. The safe way is to piece the
    > value together one byte at a time using shift and bitwise or
    > operations.


    What is the "alignment" or "endianness" of what is in the file though?


    --

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

    Hadron writes:
    > >
    > > The correct way to handle things like a WAV header is to read one
    > > value at a time, convert it to the machine endianness (the WAV header

    >
    > The values are packed in the file?


    Typically, yes.

    > > is always little endiean). Reading the header directly into a struct
    > > can lead to unpleasant surprises if the compiler inserted padding you
    > > didn't expect, and you still need to handle endian conversions.

    >
    > What is the best way? use a char* and cast it to the field in question?


    Read the header into an array of uint8_t's (no, I don't know of a
    single architecture in use today in which a char is anything other
    than eight bits. But there could certainly be one tomorrow). Take
    the right number of bytes for the field you want out of it (it may
    make more sense to do this by dereferencing several uint8_t*'s, or it
    may make more sense to dereference a uint16_t* or something). Fiddle
    to get the endianness you need. Assign the result to the field in
    your struct.

    (unfortunately, I don't know of any standard macros like a
    convertfromlittlendian32bit() which would convert a 32 bit value from
    little-endian to whatever your processor uses. Closest are the
    htons() etc macroes, which go back and forth to big-endian).
    --
    Joseph J. Pfeiffer, Jr., Ph.D. Phone -- (505) 646-1605
    Department of Computer Science FAX -- (505) 646-1002
    New Mexico State University http://www.cs.nmsu.edu/~pfeiffer

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

    Hadron writes:
    >
    > What is the "alignment" or "endianness" of what is in the file though?


    Whatever is specified in the file format specification.
    --
    Joseph J. Pfeiffer, Jr., Ph.D. Phone -- (505) 646-1605
    Department of Computer Science FAX -- (505) 646-1002
    New Mexico State University http://www.cs.nmsu.edu/~pfeiffer

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

    On 2007-01-13, Jan Panteltje wrote:
    > On a sunny day (Fri, 12 Jan 2007 19:25:08 +0000) it happened
    >=?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    >:
    >
    >>Emmanuel Fleury writes:
    >>
    >>> Mns Rullgrd wrote:
    >>>>
    >>>> 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.

    >
    > I have to still see that happen in gcc, do you have a code example?




    #include

    foobar()
    {
    struct foo
    {
    int64_t a;
    char b;
    };
    return sizeof(struct foo);
    }

    on pentium (32 bit) gcc this return 12
    on avr (8 bit) gcc this returns 9
    on a 64 bit gcc it'll probably 16

    if you can't how the above implies padding consider an array of struct foo.

    >>The WAV header has a number of fixed-size fields, that is true.
    >>However, that does not imply that the variables used to hold these
    >>values inside a program need to have the same size. They need to be
    >>at least as wide, but it doesn't hurt if they are wider if that makes
    >>for more efficient code.

    >
    > Will create problems too, as then when you write the header back, it may overflow.
    > (You cannot put a 64 bit value into a 32 bit register).
    > For exampe in a program that concatenates n wave files, the resulting could easily be > 4GB.
    > That would require a check and error abort (but you would need that anyways).


    any problems encountered there would not have been avoided by using shorter
    variables in the main program.

    Bye.
    Jasen

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

    Joe Pfeiffer writes:

    > Hadron writes:
    >>
    >> What is the "alignment" or "endianness" of what is in the file though?

    >
    > Whatever is specified in the file format specification.


    Do you have an example of this please? I am trying to draw a parallel
    between this and some other advice I read on this subject.

    If I have a C structure which is a WAV header (for example), how does
    one write it out in the correct format? Does the WAV header specifier
    the order of the constituent bytes of the integers and longs etc
    contained therein?


    --

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

    Hadron writes:

    > Joe Pfeiffer writes:
    >
    >> Hadron writes:
    >>>
    >>> What is the "alignment" or "endianness" of what is in the file though?

    >>
    >> Whatever is specified in the file format specification.

    >
    > Do you have an example of this please? I am trying to draw a parallel
    > between this and some other advice I read on this subject.
    >
    > If I have a C structure which is a WAV header (for example), how does
    > one write it out in the correct format?


    Writing is the inverse of reading. You must mask and shift a byte at
    a time of each value, and write them to the file in the proper order.
    That is unless you're unlucky enough to have a file format with an
    unusual *bit* order within bytes.

    > Does the WAV header specifier the order of the constituent bytes of
    > the integers and longs etc contained therein?


    Yes.

    --
    Mns Rullgrd
    mru@inprovide.com

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

    Hadron writes:

    > Joe Pfeiffer writes:
    >
    > > Hadron writes:
    > >>
    > >> What is the "alignment" or "endianness" of what is in the file though?

    > >
    > > Whatever is specified in the file format specification.

    >
    > Do you have an example of this please? I am trying to draw a parallel
    > between this and some other advice I read on this subject.


    I'm not quite sure what you mean (googlegooglegoogle) "wav format
    header" turns up as its first hit
    http://www.sonicspot.com/guide/wavefiles.html, where we find

    Wave File Header - RIFF Type Chunk
    Wave file headers follow the standard RIFF file format structure. The
    first 8 bytes in the file is a standard RIFF chunk header which has a
    chunk ID of "RIFF" and a chunk size equal to the file size minus the 8
    bytes used by the header. The first 4 data bytes in the "RIFF" chunk
    determines the type of resource found in the RIFF chunk. Wave files
    always use "WAVE". After the RIFF type comes all of the Wave file
    chunks that define the audio waveform.

    Offset Size Description Value
    0x00 4 Chunk ID "RIFF" (0x52494646)
    0x04 4 Chunk Data Size (file size) - 8
    0x08 4 RIFF Type "WAVE" (0x57415645)

    Assuming the size is in octets, and the author of the web page is
    being sloppy in exactly the way you're being advised not to be, the
    first eight bits contains 0x52, the next 0x49, the next 0x46, the one
    after that another 0x46.

    > If I have a C structure which is a WAV header (for example), how does
    > one write it out in the correct format? Does the WAV header specifier
    > the order of the constituent bytes of the integers and longs etc
    > contained therein?


    Create a "header" in the right format: an array of octets in the
    format you need it to be -- exactly backwards from the procedure in my
    previous post. The write the whole header as a chunk.

    Someplace, there is a specification of the WAV format header at the
    level of detail you need. Maybe in the code for something that
    already writes WAV files -- that's just one of the beauties of open
    source.
    --
    Joseph J. Pfeiffer, Jr., Ph.D. Phone -- (505) 646-1605
    Department of Computer Science FAX -- (505) 646-1002
    New Mexico State University http://www.cs.nmsu.edu/~pfeiffer

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

    On a sunny day (Sat, 13 Jan 2007 22:27:07 +0000) it happened
    =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    :
    >
    >> The discussion was about 32 bits to 64 bits.
    >> The more bits the more bloat this example is.
    >> int as return (where a bool is used),
    >> and int as argument (where a 8 bits char is used).

    >
    >An int takes no more space than a char in a register. When arguments
    >are passed on the stack, they are still typically aligned on word
    >boundaries, so there would be no savings there either.


    Back to inline asm ;-)


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

    On a sunny day (13 Jan 2007 23:09:28 -0700) it happened Joe Pfeiffer
    wrote in <1b8xg66sx3.fsf@viper.cs.nmsu.edu>:

    >
    >Assuming the size is in octets, and the author of the web page is
    >being sloppy in exactly the way you're being advised not to be, the
    >first eight bits contains 0x52, the next 0x49, the next 0x46, the one
    >after that another 0x46.
    >
    >> If I have a C structure which is a WAV header (for example), how does
    >> one write it out in the correct format? Does the WAV header specifier
    >> the order of the constituent bytes of the integers and longs etc
    >> contained therein?

    >
    >Create a "header" in the right format: an array of octets in the
    >format you need it to be -- exactly backwards from the procedure in my
    >previous post. The write the whole header as a chunk.
    >
    >Someplace, there is a specification of the WAV format header at the
    >level of detail you need. Maybe in the code for something that
    >already writes WAV files -- that's just one of the beauties of open
    >source.


    It is open, it is (or was) somewhere on the MS site.
    As is for example ASF (video) format etc.
    The first example I gave _is_ correct, and the endianes is low byte first.

    typedef struct
    { /* header for WAV-Files */
    char main_chunk[4]; /* 'RIFF' */
    uint32_t length; /* length of file */
    char chunk_type[4]; /* 'WAVE' */
    char sub_chunk[4]; /* 'fmt ' */
    uint32_t length_chunk; /* length sub_chunk, always 16 bytes */
    uint16_t format; /* always 1 = PCM-Code */
    uint16_t modus; /* 1 = Mono, 2 = Stereo */
    uint32_t sample_fq; /* Sample Freq */
    uint32_t byte_p_sec; /* Data per sec */
    uint16_t byte_p_spl; /* bytes per sample, 1=8 bit, 2=16 bit (mono) 2=8 bit, 4=16 bit (stereo) */
    uint16_t bit_p_spl; /* bits per sample, 8, 12, 16 */
    char data_chunk[4]; /* 'data' */
    uint32_t data_length; /* length of data */
    } wave_header;


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

    Jan Panteltje writes:

    > On a sunny day (13 Jan 2007 23:09:28 -0700) it happened Joe Pfeiffer
    > wrote in <1b8xg66sx3.fsf@viper.cs.nmsu.edu>:
    >
    >>
    >>Assuming the size is in octets, and the author of the web page is
    >>being sloppy in exactly the way you're being advised not to be, the
    >>first eight bits contains 0x52, the next 0x49, the next 0x46, the one
    >>after that another 0x46.
    >>
    >>> If I have a C structure which is a WAV header (for example), how does
    >>> one write it out in the correct format? Does the WAV header specifier
    >>> the order of the constituent bytes of the integers and longs etc
    >>> contained therein?

    >>
    >>Create a "header" in the right format: an array of octets in the
    >>format you need it to be -- exactly backwards from the procedure in my
    >>previous post. The write the whole header as a chunk.
    >>
    >>Someplace, there is a specification of the WAV format header at the
    >>level of detail you need. Maybe in the code for something that
    >>already writes WAV files -- that's just one of the beauties of open
    >>source.

    >
    > It is open, it is (or was) somewhere on the MS site.
    > As is for example ASF (video) format etc.
    > The first example I gave _is_ correct, and the endianes is low byte first.
    >
    > typedef struct
    > { /* header for WAV-Files */
    > char main_chunk[4]; /* 'RIFF' */
    > uint32_t length; /* length of file */
    > char chunk_type[4]; /* 'WAVE' */
    > char sub_chunk[4]; /* 'fmt ' */
    > uint32_t length_chunk; /* length sub_chunk, always 16 bytes */
    > uint16_t format; /* always 1 = PCM-Code */
    > uint16_t modus; /* 1 = Mono, 2 = Stereo */
    > uint32_t sample_fq; /* Sample Freq */
    > uint32_t byte_p_sec; /* Data per sec */
    > uint16_t byte_p_spl; /* bytes per sample, 1=8 bit, 2=16 bit (mono) 2=8 bit, 4=16 bit (stereo) */
    > uint16_t bit_p_spl; /* bits per sample, 8, 12, 16 */
    > char data_chunk[4]; /* 'data' */
    > uint32_t data_length; /* length of data */
    > } wave_header;


    As a peculiar way of defining the file format, this describes the most
    common layout of WAV files. It is possible, and not uncommon, to have
    other chunks before the 'fmt' chunk.

    Pretending, for the sake of argument, that your struct above is an
    accurate description, it is still a bad idea to read the beginning of
    a file directly into such a struct. For instance, it will break badly
    on a machine with 32-bit char type.

    --
    Mns Rullgrd
    mru@inprovide.com

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

    Jan Panteltje writes:

    > On a sunny day (Sat, 13 Jan 2007 22:27:07 +0000) it happened
    > =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    > :
    >>
    >>> The discussion was about 32 bits to 64 bits.
    >>> The more bits the more bloat this example is.
    >>> int as return (where a bool is used),
    >>> and int as argument (where a 8 bits char is used).

    >>
    >>An int takes no more space than a char in a register. When arguments
    >>are passed on the stack, they are still typically aligned on word
    >>boundaries, so there would be no savings there either.

    >
    > Back to inline asm ;-)


    I thought we were talking about writing portable code.

    --
    Mns Rullgrd
    mru@inprovide.com

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

    On a sunny day (Sun, 14 Jan 2007 13:12:47 +0000) it happened
    =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    :

    >Jan Panteltje writes:
    >
    >> On a sunny day (Sat, 13 Jan 2007 22:27:07 +0000) it happened
    >> =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    >> :
    >>>
    >>>> The discussion was about 32 bits to 64 bits.
    >>>> The more bits the more bloat this example is.
    >>>> int as return (where a bool is used),
    >>>> and int as argument (where a 8 bits char is used).
    >>>
    >>>An int takes no more space than a char in a register. When arguments
    >>>are passed on the stack, they are still typically aligned on word
    >>>boundaries, so there would be no savings there either.

    >>
    >> Back to inline asm ;-)

    >
    >I thought we were talking about writing portable code.


    Well honestly, this afternoon I have been re-writing that piece of
    wave processing stuff, and what you wind up with is something like this:

    uint8_t *buffer[44];// wave header is always 44 bytes
    .....

    a = fread(buffer, sizeof(char), 44, ifptr[i]);
    .......
    for(i = 0 i < files; i++)
    {
    ......
    in_header[i] -> length = buffer[ 4] | (buffer[ 5] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
    .....
    in_header[i] -> length_chunk = buffer[16] | (buffer[17] << 8) | (buffer[18] << 16) | (buffer[19] << 24);
    in_header[i] -> format = buffer[20] | (buffer[21] << 8);
    in_header[i] -> modus = buffer[22] | (buffer[23] << 8);
    in_header[i] -> sample_fq = buffer[24] | (buffer[25] << 8) | (buffer[26] << 16) | (buffer[27] << 24);
    in_header[i] -> byte_p_sec = buffer[28] | (buffer[29] << 8) | (buffer[30] << 16) | (buffer[31] << 24);
    in_header[i] -> byte_p_spl = buffer[32] | (buffer[33] << 8);
    in_header[i] -> bit_p_spl = buffer[34] | (buffer[35] << 8);
    in_header[i] -> data_length = buffer[40] | (buffer[41] << 8) | (buffer[42] << 16) | (buffer[43] << 24);
    .......
    }

    This is assuming I want to keep a structure around, and I do because that makes referencing
    easier (this thing processes n wavefiles).

    Apart from the structure it is as much, or more work as coding in asm.

    The real truth about C is that is is _not_ portable :-)
    Take any system, micro controller, computer, you always need to modify.
    I have ported things from one processor in asm, to an other processor in asm, in _less_ time then
    I can port some C code... (this is me of course).
    :-)





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

    On a sunny day (Sun, 14 Jan 2007 13:12:23 +0000) it happened
    =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    :

    >Jan Panteltje writes:
    >
    >> On a sunny day (13 Jan 2007 23:09:28 -0700) it happened Joe Pfeiffer
    >> wrote in <1b8xg66sx3.fsf@viper.cs.nmsu.edu>:
    >>
    >>>
    >>>Assuming the size is in octets, and the author of the web page is
    >>>being sloppy in exactly the way you're being advised not to be, the
    >>>first eight bits contains 0x52, the next 0x49, the next 0x46, the one
    >>>after that another 0x46.
    >>>
    >>>> If I have a C structure which is a WAV header (for example), how does
    >>>> one write it out in the correct format? Does the WAV header specifier
    >>>> the order of the constituent bytes of the integers and longs etc
    >>>> contained therein?
    >>>
    >>>Create a "header" in the right format: an array of octets in the
    >>>format you need it to be -- exactly backwards from the procedure in my
    >>>previous post. The write the whole header as a chunk.
    >>>
    >>>Someplace, there is a specification of the WAV format header at the
    >>>level of detail you need. Maybe in the code for something that
    >>>already writes WAV files -- that's just one of the beauties of open
    >>>source.

    >>
    >> It is open, it is (or was) somewhere on the MS site.
    >> As is for example ASF (video) format etc.
    >> The first example I gave _is_ correct, and the endianes is low byte first.
    >>
    >> typedef struct
    >> { /* header for WAV-Files */
    >> char main_chunk[4]; /* 'RIFF' */
    >> uint32_t length; /* length of file */
    >> char chunk_type[4]; /* 'WAVE' */
    >> char sub_chunk[4]; /* 'fmt ' */
    >> uint32_t length_chunk; /* length sub_chunk, always 16 bytes */
    >> uint16_t format; /* always 1 = PCM-Code */
    >> uint16_t modus; /* 1 = Mono, 2 = Stereo */
    >> uint32_t sample_fq; /* Sample Freq */
    >> uint32_t byte_p_sec; /* Data per sec */
    >> uint16_t byte_p_spl; /* bytes per sample, 1=8 bit, 2=16 bit (mono) 2=8 bit, 4=16 bit (stereo) */
    >> uint16_t bit_p_spl; /* bits per sample, 8, 12, 16 */
    >> char data_chunk[4]; /* 'data' */
    >> uint32_t data_length; /* length of data */
    >> } wave_header;

    >
    >As a peculiar way of defining the file format, this describes the most
    >common layout of WAV files. It is possible, and not uncommon, to have
    >other chunks before the 'fmt' chunk.


    Oh yes, but never came accorss.

    >Pretending, for the sake of argument, that your struct above is an
    >accurate description, it is still a bad idea to read the beginning of
    >a file directly into such a struct. For instance, it will break badly
    >on a machine with 32-bit char type.


    But we did agree on that now did not we?

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

    Jan Panteltje writes:

    > On a sunny day (Sun, 14 Jan 2007 13:12:47 +0000) it happened
    > =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    > :
    >
    >>Jan Panteltje writes:
    >>
    >>> On a sunny day (Sat, 13 Jan 2007 22:27:07 +0000) it happened
    >>> =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= wrote in
    >>> :
    >>>>
    >>>>> The discussion was about 32 bits to 64 bits.
    >>>>> The more bits the more bloat this example is.
    >>>>> int as return (where a bool is used),
    >>>>> and int as argument (where a 8 bits char is used).
    >>>>
    >>>>An int takes no more space than a char in a register. When arguments
    >>>>are passed on the stack, they are still typically aligned on word
    >>>>boundaries, so there would be no savings there either.
    >>>
    >>> Back to inline asm ;-)

    >>
    >>I thought we were talking about writing portable code.

    >
    > Well honestly, this afternoon I have been re-writing that piece of
    > wave processing stuff, and what you wind up with is something like this:
    >
    > uint8_t *buffer[44];// wave header is always 44 bytes
    > ....
    >
    > a = fread(buffer, sizeof(char), 44, ifptr[i]);
    > ......
    > for(i = 0 i < files; i++)
    > {
    > .....
    > in_header[i] -> length = buffer[ 4] | (buffer[ 5] << 8) | (buffer[6] << 16) | (buffer[7] << 24);


    [...]

    > This is assuming I want to keep a structure around, and I do because
    > that makes referencing easier (this thing processes n wavefiles).
    >
    > Apart from the structure it is as much, or more work as coding in asm.


    You'd normally write a set of macros for extracting integers of
    various sizes and byte orders from an array of bytes. Then that bit
    of code would look much nicer.

    > The real truth about C is that is is _not_ portable :-)


    The *real* truth about C is that it is as portable or not as the code
    is written. Nothing in the language itself enforces neither
    portability nor lack thereof.

    > Take any system, micro controller, computer, you always need to
    > modify. I have ported things from one processor in asm, to an other
    > processor in asm, in _less_ time then I can port some C
    > code... (this is me of course). :-)


    Well, then the C code wasn't portably written. Had it been properly
    written, only minimal changes, if any, would have been required.
    Where I work, we run the same code on at least a dozen different CPUs
    and variants, using about as many different compilers. With a little
    discipline, it all works rather smoothly.

    --
    Mns Rullgrd
    mru@inprovide.com

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

    Jan Panteltje writes:
    >
    > Well honestly, this afternoon I have been re-writing that piece of
    > wave processing stuff, and what you wind up with is something like this:
    >
    > uint8_t *buffer[44];// wave header is always 44 bytes


    Are you sure you didn't mean

    uint8_t buffer[44];// wave header is always 44 bytes

    (no asterisk)?
    >
    > Apart from the structure it is as much, or more work as coding in asm.
    >
    > The real truth about C is that is is _not_ portable :-)


    The real truth is that no language will ever be portable; your code
    has to be portable.
    --
    Joseph J. Pfeiffer, Jr., Ph.D. Phone -- (505) 646-1605
    Department of Computer Science FAX -- (505) 646-1002
    New Mexico State University http://www.cs.nmsu.edu/~pfeiffer

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

    Joe Pfeiffer writes:

    > Jan Panteltje writes:
    >>
    >> Well honestly, this afternoon I have been re-writing that piece of
    >> wave processing stuff, and what you wind up with is something like this:
    >>
    >> uint8_t *buffer[44];// wave header is always 44 bytes

    >
    > Are you sure you didn't mean
    >
    > uint8_t buffer[44];// wave header is always 44 bytes
    >
    > (no asterisk)?


    That's probably what he meant. The comment about 44 bytes is a lie
    too. There are *many* MS WAV files with longer headers.

    >> Apart from the structure it is as much, or more work as coding in asm.
    >>
    >> The real truth about C is that is is _not_ portable :-)

    >
    > The real truth is that no language will ever be portable; your code
    > has to be portable.


    All that can be said is that certain languages have the potential to
    be used for portable code. C is one of them. Assembly language is
    not.

    --
    Mns Rullgrd
    mru@inprovide.com

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

    On a sunny day (14 Jan 2007 10:33:10 -0700) it happened Joe Pfeiffer
    wrote in <1birf97bu1.fsf@viper.cs.nmsu.edu>:

    >Jan Panteltje writes:
    >>
    >> Well honestly, this afternoon I have been re-writing that piece of
    >> wave processing stuff, and what you wind up with is something like this:
    >>
    >> uint8_t *buffer[44];// wave header is always 44 bytes

    >
    >Are you sure you didn't mean
    >
    >uint8_t buffer[44];// wave header is always 44 bytes
    >
    >(no asterisk)?


    Yes, you are right.


    >> Apart from the structure it is as much, or more work as coding in asm.
    >>
    >> The real truth about C is that is is _not_ portable :-)

    >
    >The real truth is that no language will ever be portable; your code
    >has to be portable.


    Well, I release as C source (this program).
    My main problem is the amount of emails I get when I f*ck up.
    In the past for this program (long before I had access to an AMD64)
    I got these error reports 'Your soft does not work on my new AMD64'.
    A bit of back and forth emailing fixed it.

    And the same perhaps when somebody emails:
    'It does not work on a Cray super computer'.

    Main fear is a thousand of these email after the next release....
    I have to answer these all ;-)
    Well I try anyways.
    So I am still testing now with huge files and nasty stuff.

    As to your last remark:
    It is not possible to write 100 % portable code (in C or any language).

    If at all possible I write in the simplest subset of C, I came from C/80,
    and C/80 programs compile even today.
    But there is no way I can take a gcc program and use it with C/80, even
    just because there is no libc.
    Many smaller micros do not have libc, and severe restrictions on memory,
    maybe have a different architecture, IO and special hardware considerations.
    If you want to use these (and somebody mentioned DSP too), you will have to
    adapt, to make best use of the provided hardware facilities.

    So, in short, code is not really portable, except in a narrow area,
    even on the PC, going from 32 to 64 bit gives plenty of things to think about.
    I hope to get a PS3 in a few month, I expect 'for(i = 0; i < 10; i++)'
    to work, but not much more, especially on the co-processors ;-)

    Anyways I added some new features to my program today, do you want to be
    mentioned as responsible for the changes in reading in the structures?
    ;-)








+ Reply to Thread
Page 2 of 3 FirstFirst 1 2 3 LastLast