packed datastructure - how to define?

Discussion in 'C Programming' started by =?ISO-8859-15?Q?J=FCrgen?= Hochwald, Nov 3, 2004.

  1. Hi

    Maybe this is a simple question, but I don't know how to solve.

    Background: A weather station connected to the serial port sends data
    packets. This data packets are containing variables fom one byte up to 4
    byted in mixed order. Now I want to define a structure to overlay it with
    UNION over the receive buffer for easily access to the single values in the
    data packet.
    The problem is, that I cannot defind a variable, which only reserves one
    byte of memory. A simple 'char' or 'char[1]' eats 4 bytes and all following
    variables are not matching.

    How can I define a variable, which uses exactly one byte ?


    Here is a small text app:
    ------------------------------------------
    #include <stdio.h>
    #include <stdlib.h>

    struct data {
    int i;
    char c;
    int j;
    };

    union ovr {
    struct data d;
    char c[16];
    };

    int main(void) {
    union ovr d;
    int l;

    for (l=0;l<16;l++)
    d.c[l]=l;

    printf("size=%d\n",sizeof(d));
    printf("i=%X\n",d.d.i);
    printf("c=%X\n",d.d.c);
    printf("j=%X\n",d.d.j);
    }
    --------------------------------
    and the output:
    size=16
    i=3020100
    c=4
    j=B0A0908

    To overlay the data packet correct, j must be 8070605.


    --
    Jürgen
    www.cfjh.de
    =?ISO-8859-15?Q?J=FCrgen?= Hochwald, Nov 3, 2004
    #1
    1. Advertising

  2. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Michael Mair Guest

    Hi Juergen,

    Jürgen Hochwald wrote:
    > Maybe this is a simple question, but I don't know how to solve.
    >
    > Background: A weather station connected to the serial port sends data
    > packets. This data packets are containing variables fom one byte up to 4
    > byted in mixed order. Now I want to define a structure to overlay it with
    > UNION over the receive buffer for easily access to the single values in the
    > data packet.
    > The problem is, that I cannot defind a variable, which only reserves one
    > byte of memory. A simple 'char' or 'char[1]' eats 4 bytes and all following
    > variables are not matching.
    >
    > How can I define a variable, which uses exactly one byte ?
    >
    >
    > Here is a small text app:
    > ------------------------------------------
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > struct data {
    > int i;
    > char c;
    > int j;
    > };
    >
    > union ovr {
    > struct data d;
    > char c[16];
    > };
    >
    > int main(void) {
    > union ovr d;
    > int l;
    >
    > for (l=0;l<16;l++)
    > d.c[l]=l;
    >
    > printf("size=%d\n",sizeof(d));
    > printf("i=%X\n",d.d.i);
    > printf("c=%X\n",d.d.c);
    > printf("j=%X\n",d.d.j);
    > }
    > --------------------------------
    > and the output:
    > size=16
    > i=3020100
    > c=4
    > j=B0A0908
    >
    > To overlay the data packet correct, j must be 8070605.


    There are several issues here:
    - If you want to access something bytewise, use unsigned char
    - The size of a char/signed char/unsigned char _always_ is one
    byte
    - A byte is not necessarily eight bit but at least so much.
    Check the symbolic constant CHAR_BIT from <limits.h> to find
    out the exact ratio
    If you have a C99 compiler with the integer types in <stdint.h>,
    then you can use the type uint8_t. 8 Bits often are referred to
    as "octet"
    - sizeof(int)>=sizeof(unsigned char), so your assumptions about
    a certain ratio may be wrong
    - In a structure, there may be padding bytes between the members
    if there are alignment requirements. If sizeof(int) > 1 and
    ints have to be sizeof(int)-aligned (that is, their address
    can be divided by sizeof(int) without remainder), then there
    are probably sizeof(int)-1 padding bytes between the c and j
    members of your structure.
    As an aside: If you have larger structures then it makes sense
    to put the variables with the largest type first and then go
    down in size -- this often leads to smaller structures.
    - The bytes of types with size >1 are not necessarily ordered as
    you assume. Thus,
    unsigned int i=1;
    unsigned char lowestbyte=((unsigned char *)&i)[0];
    may yield lowestbyte==1 or lowestbyte==0.

    So, check the necessary size, use
    union ovr {
    struct data d;
    unsigned char c[sizeof(struct data)];
    };
    or do not use a union at all but access the structure representation
    directly, find out the byte order (or: rather use shifting and masking
    instead of access by unsigned char for portable code), and so on.

    BTW: The offsetof macro yields the offset in bytes of a member of
    a structure with respect to the start of the structure.

    The comp.lang.c FAQ addresses several of these issues in detail.
    It has been posted here on November 1 and can also be found at
    http://www.eskimo.com/~scs/C-faq/top.html
    The ASCII version is up to date, unlike the HTML version.


    HTH
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Nov 3, 2004
    #2
    1. Advertising

  3. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Default User Guest

    =?ISO-8859-15?Q?J=FCrgen?= Hochwald wrote:


    > The problem is, that I cannot defind a variable, which only reserves

    one
    > byte of memory. A simple 'char' or 'char[1]' eats 4 bytes and all

    following
    > variables are not matching.


    No it doesn't, or it's not a C compiler. What makes you think it's
    taking up more than one byte?




    > struct data {
    > int i;
    > char c;
    > int j;
    > };
    >
    > union ovr {
    > struct data d;
    > char c[16];
    > };
    >
    > int main(void) {
    > union ovr d;
    > int l;
    >
    > for (l=0;l<16;l++)
    > d.c[l]=l;
    >
    > printf("size=%d\n",sizeof(d));
    > printf("i=%X\n",d.d.i);
    > printf("c=%X\n",d.d.c);
    > printf("j=%X\n",d.d.j);
    > }
    > --------------------------------
    > and the output:
    > size=16
    > i=3020100
    > c=4
    > j=B0A0908



    Ah, it isn't the data size that is the problem, it's struct alignment.

    There is no way in ISO standard C to define packed structs. Your
    implementation may provide a way.




    Brian
    Default User, Nov 3, 2004
    #3
  4. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Alan Balmer Guest

    On Wed, 03 Nov 2004 22:45:19 +0100, Jürgen Hochwald <>
    wrote:

    >Hi
    >
    >Maybe this is a simple question, but I don't know how to solve.
    >
    >Background: A weather station connected to the serial port sends data
    >packets. This data packets are containing variables fom one byte up to 4
    >byted in mixed order. Now I want to define a structure to overlay it with
    >UNION over the receive buffer for easily access to the single values in the
    >data packet.
    >The problem is, that I cannot defind a variable, which only reserves one
    >byte of memory. A simple 'char' or 'char[1]' eats 4 bytes and all following
    >variables are not matching.
    >
    >How can I define a variable, which uses exactly one byte ?


    <snip>
    >
    >struct data {
    > int i;
    > char c;
    > int j;
    >};
    >

    <snip>
    >

    You have the answer in your subject line, but data packing in
    structures is implementation and platform dependent and off topic
    here. Your compiler may have a switch or pragma to force the structure
    to be packed. OTOH, your platform may not allow access of j on an odd
    boundary. You might consider alternatives, such as defining an int and
    copying bytes 5-8 into it. Not a robust, portable method, but it will
    probably work.

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 3, 2004
    #4
  5. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Alan Balmer Guest

    On 3 Nov 2004 14:26:04 -0800, "Default User" <>
    wrote:

    >
    >=?ISO-8859-15?Q?J=FCrgen?= Hochwald wrote:
    >
    >
    >> The problem is, that I cannot defind a variable, which only reserves

    >one
    >> byte of memory. A simple 'char' or 'char[1]' eats 4 bytes and all

    >following
    >> variables are not matching.

    >
    >No it doesn't, or it's not a C compiler. What makes you think it's
    >taking up more than one byte?
    >
    >

    The byte in the structure may be (and obviously is, in this case)
    padded to align the int on a particular boundary..
    >
    >
    >> struct data {
    >> int i;
    >> char c;
    >> int j;
    >> };


    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 3, 2004
    #5
  6. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Eric Sosman Guest

    Jürgen Hochwald wrote:
    > Hi
    >
    > Maybe this is a simple question, but I don't know how to solve.
    >
    > Background: A weather station connected to the serial port sends data
    > packets. This data packets are containing variables fom one byte up to 4
    > byted in mixed order. Now I want to define a structure to overlay it with
    > UNION over the receive buffer for easily access to the single values in the
    > data packet.
    > The problem is, that I cannot defind a variable, which only reserves one
    > byte of memory. A simple 'char' or 'char[1]' eats 4 bytes and all following
    > variables are not matching.
    >
    > How can I define a variable, which uses exactly one byte ?


    This is Question 2.12 in the comp.lang.c Frequently
    Asked Questions (FAQ) list

    http://www.eskimo.com/~scs/C-faq/faq.html

    Unfortunately, the methods mentioned in the answer are
    not portable (and are described as such). If you want a
    portable solution, you will have to abandon the attempt
    to make your program's variables match the externally-
    defined format. Instead, receive the data packets into
    an array of `unsigned char' and then copy the appropriate
    bytes into your program's struct.

    At first this may seem terribly inefficient, but it
    actually is not. Your C compiler may be able to squeeze
    the holes out of a struct, but there will probably be a
    time penalty for every access to an unaligned field. The
    penalty may be small or large (or even huge, on some kinds
    of hardware), so spending a few cycles to copy the data
    into a properly-aligned struct can be worth while.

    Also, the copying step gives you an opportunity to
    resolve things like "endian-ness" issues. If the weather
    station likes to send a four-byte integer's high-order
    byte first but your computer prefers to start with the
    low-order byte, you would need to fiddle with the data
    anyhow in order to make sense of it.

    All in all, the "extra" code to reconcile the internal
    and external format is seldom wasteful and often useful.

    --
    Eric Sosman, Nov 3, 2004
    #6
  7. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Default User Guest

    Alan Balmer wrote:
    > On 3 Nov 2004 14:26:04 -0800, "Default User"

    <>
    > wrote:


    > >No it doesn't, or it's not a C compiler. What makes you think it's
    > >taking up more than one byte?
    > >
    > >

    > The byte in the structure may be (and obviously is, in this case)
    > padded to align the int on a particular boundary..



    So, that doesn't have anything to do with the OP's contention that he
    can't define a data type of size 1.

    You also snipped my further remark, after he listed the struct size:

    > > Ah, it isn't the data size that is the problem, it's struct

    alignment.



    Brian
    Default User, Nov 3, 2004
    #7
  8. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Alan Balmer Guest

    On 3 Nov 2004 15:21:46 -0800, "Default User" <>
    wrote:

    >
    >Alan Balmer wrote:
    >> On 3 Nov 2004 14:26:04 -0800, "Default User"

    ><>
    >> wrote:

    >
    >> >No it doesn't, or it's not a C compiler. What makes you think it's
    >> >taking up more than one byte?
    >> >
    >> >

    >> The byte in the structure may be (and obviously is, in this case)
    >> padded to align the int on a particular boundary..

    >
    >
    >So, that doesn't have anything to do with the OP's contention that he
    >can't define a data type of size 1.


    That was not his contention, as was obvious in the context which you
    snipped.
    >
    >You also snipped my further remark, after he listed the struct size:
    >
    >> > Ah, it isn't the data size that is the problem, it's struct

    >alignment.
    >

    And realizing that later, you didn't go back and edit your first
    impulse?

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 3, 2004
    #8
  9. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Default User Guest

    Alan Balmer wrote:

    > And realizing that later, you didn't go back and edit your first
    > impulse?



    Why didn't you?



    Brian
    Default User, Nov 4, 2004
    #9
  10. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Alan Balmer Guest

    On 3 Nov 2004 16:04:21 -0800, "Default User" <>
    wrote:

    >
    >Alan Balmer wrote:
    >
    >> And realizing that later, you didn't go back and edit your first
    >> impulse?

    >
    >
    >Why didn't you?


    I don't edit your writing unless you pay me to do so.

    End of thread, afaic.

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 4, 2004
    #10
  11. =?ISO-8859-15?Q?J=FCrgen?= Hochwald

    Default User Guest

    Alan Balmer wrote:
    > On 3 Nov 2004 16:04:21 -0800, "Default User"

    <>
    > wrote:
    >
    > >
    > >Alan Balmer wrote:
    > >
    > >> And realizing that later, you didn't go back and edit your first
    > >> impulse?

    > >
    > >
    > >Why didn't you?

    >
    > I don't edit your writing unless you pay me to do so.


    That's not what I said, was it? And you did edit my writing, snipping
    out part of my message to make your point stronger.



    Brian
    Default User, Nov 4, 2004
    #11
  12. On 4 Nov 2004 09:05:36 -0800, in comp.lang.c , "Default User"
    <> wrote:
    >
    >Alan Balmer wrote:


    (stuff.)
    Gentlemen, please choose your seconds.
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
    Mark McIntyre, Nov 4, 2004
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anony!

    Set DataStructure

    Anony!, Aug 12, 2004, in forum: Java
    Replies:
    2
    Views:
    391
    Anony!
    Aug 13, 2004
  2. Sharp

    Index-based datastructure

    Sharp, Mar 14, 2005, in forum: Java
    Replies:
    1
    Views:
    323
    Chris Uppal
    Mar 14, 2005
  3. Replies:
    3
    Views:
    384
    shakah
    Jun 23, 2005
  4. Santosh

    Datastructure design

    Santosh, Nov 19, 2003, in forum: C Programming
    Replies:
    6
    Views:
    378
    pandy
    Nov 20, 2003
  5. Prateek Basu

    Datastructure and Algorithms

    Prateek Basu, Jan 23, 2004, in forum: C Programming
    Replies:
    4
    Views:
    2,208
    Prateek Basu
    Jan 24, 2004
Loading...

Share This Page