variable length record using struct/union - help

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Panchal V

    variable length record using struct/union - help

    I want to access a variable length record in C, the format is as
    follows :

    +---+---+-----------+
    | A | L | D A T A |
    +---+---+-----------+
    A - Some Data (1 BYTE)
    L - Length the Data that follows (1 BYTE)
    then actual data

    I want to access and represent this record using struct/union in c,
    how can I do it...
    Data is variable length, L tell the length of data (in bytes) that
    follows...
    So that I can access it in this manner :
    pData->A = 56;
    pData->data[pData->L - 1] = '\0';



    Now I want to represent
    +---+---+-----------+---+
    | A | L | D A T A | B |
    +---+---+-----------+---+

    where B - is some data ( 1 byte)
    I want to access it like this
    pData->B
    (Remember it is after variable length data)

    How can I do it....????

    -Neo
  • Mark A. Odell

    #2
    Re: variable length record using struct/union - help

    vks_vikas@redif fmail.com (Panchal V) wrote in
    news:13fbeb79.0 402020600.1afa8 655@posting.goo gle.com:
    [color=blue]
    > Now I want to represent
    > +---+---+-----------+---+
    >| A | L | D A T A | B |
    > +---+---+-----------+---+
    >
    > where B - is some data ( 1 byte)
    > I want to access it like this
    > pData->B
    > (Remember it is after variable length data)
    >
    > How can I do it....????[/color]

    You can't.

    --
    - Mark ->
    --

    Comment

    • nrk

      #3
      Re: variable length record using struct/union - help

      Panchal V wrote:
      [color=blue]
      > I want to access a variable length record in C, the format is as
      > follows :
      >
      > +---+---+-----------+
      > | A | L | D A T A |
      > +---+---+-----------+
      > A - Some Data (1 BYTE)
      > L - Length the Data that follows (1 BYTE)
      > then actual data
      >
      > I want to access and represent this record using struct/union in c,
      > how can I do it...
      > Data is variable length, L tell the length of data (in bytes) that
      > follows...
      > So that I can access it in this manner :
      > pData->A = 56;
      > pData->data[pData->L - 1] = '\0';
      >
      >
      >
      > Now I want to represent
      > +---+---+-----------+---+
      > | A | L | D A T A | B |
      > +---+---+-----------+---+
      >
      > where B - is some data ( 1 byte)
      > I want to access it like this
      > pData->B
      > (Remember it is after variable length data)
      >
      > How can I do it....????
      >[/color]

      You can't really do what you want. But a reasonable alternative might be to
      define something like:

      struct Record {
      unsigned char A;
      unsigned char L;
      unsigned char *data;
      };

      #define GETB(rptr) ((rptr)->data[(rptr)->L])
      #define SETB(rptr, val) ((rptr)->data[(rptr)->L] = val)

      and use it like this:
      struct Record *rptr;
      ...
      unsigned char b = GETB(rptr);
      ...
      SETB(rptr, b);

      -nrk.
      [color=blue]
      > -Neo[/color]

      --
      Remove devnull for email

      Comment

      • xarax

        #4
        Re: variable length record using struct/union - help

        "Panchal V" <vks_vikas@redi ffmail.com> wrote in message
        news:13fbeb79.0 402020600.1afa8 655@posting.goo gle.com...[color=blue]
        > I want to access a variable length record in C, the format is as
        > follows :
        >
        > +---+---+-----------+
        > | A | L | D A T A |
        > +---+---+-----------+
        > A - Some Data (1 BYTE)
        > L - Length the Data that follows (1 BYTE)
        > then actual data
        >
        > I want to access and represent this record using struct/union in c,
        > how can I do it...
        > Data is variable length, L tell the length of data (in bytes) that
        > follows...
        > So that I can access it in this manner :
        > pData->A = 56;
        > pData->data[pData->L - 1] = '\0';
        >
        >
        >
        > Now I want to represent
        > +---+---+-----------+---+
        > | A | L | D A T A | B |
        > +---+---+-----------+---+
        >
        > where B - is some data ( 1 byte)
        > I want to access it like this
        > pData->B
        > (Remember it is after variable length data)
        >
        > How can I do it....????[/color]

        =============== =============== =
        /* Use the "struct hack" approach. */
        typedef struct header
        {
        unsigned char a; /* something */
        unsigned char len; /* number of "data" elements */
        unsigned char data[1]; /* element count is a lie */
        } Header, * Header_P;


        /*
        * get the value of "unsigned char B" that follows
        * the variable-length "data" array.
        */
        unsigned char getB(Header_P header_p)
        {
        return *(header_p->len + header_p->data);
        }

        /*
        * set the value of "unsigned char B" that
        * follows the "data" array.
        */
        void setB(Header_P header_p, unsigned char b)
        {
        *(header_p->len + header_p->data) = b;
        }
        =============== =============== =


        --
        ----------------------------
        Jeffrey D. Smith
        Farsight Systems Corporation
        24 BURLINGTON DRIVE
        LONGMONT, CO 80501-6906

        z/Debug debugs your Systems/C programs running on IBM z/OS!
        Are ISV upgrade fees too high? Check our custom product development!


        Comment

        • Leor Zolman

          #5
          Re: variable length record using struct/union - help

          On 2 Feb 2004 06:00:01 -0800, vks_vikas@redif fmail.com (Panchal V)
          wrote:
          [color=blue]
          >I want to access a variable length record in C, the format is as
          >follows :
          >
          >+---+---+-----------+
          >| A | L | D A T A |
          >+---+---+-----------+
          >A - Some Data (1 BYTE)
          >L - Length the Data that follows (1 BYTE)
          >then actual data
          >
          >I want to access and represent this record using struct/union in c,
          >how can I do it...
          >Data is variable length, L tell the length of data (in bytes) that
          >follows...
          >So that I can access it in this manner :
          >pData->A = 56;
          >pData->data[pData->L - 1] = '\0';
          >
          >
          >
          >Now I want to represent
          >+---+---+-----------+---+
          >| A | L | D A T A | B |
          >+---+---+-----------+---+
          >
          >where B - is some data ( 1 byte)
          >I want to access it like this
          >pData->B
          >(Remember it is after variable length data)
          >
          >How can I do it....????[/color]

          If, in your structure, you represent your "data" with a _pointer_ and
          allocate storage for it dynamically on-the-fly as you are reading your
          data in, then you'll be able to use your desired syntax (since
          subscripting works for pointers "as if" they were arrays).
          -leor
          [color=blue]
          >
          >-Neo[/color]

          Leor Zolman
          BD Software
          leor@bdsoft.com
          www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
          C++ users: Download BD Software's free STL Error Message
          Decryptor at www.bdsoft.com/tools/stlfilt.html

          Comment

          • Kevin D. Quitt

            #6
            Re: variable length record using struct/union - help

            On 2 Feb 2004 06:00:01 -0800, vks_vikas@redif fmail.com (Panchal V) wrote:

            [color=blue]
            >I want to access a variable length record in C, the format is as
            >follows :
            >
            >+---+---+-----------+
            >| A | L | D A T A |
            >+---+---+-----------+
            >A - Some Data (1 BYTE)
            >L - Length the Data that follows (1 BYTE)
            >then actual data
            >
            >I want to access and represent this record using struct/union in c,
            >how can I do it...
            >Data is variable length, L tell the length of data (in bytes) that
            >follows...
            >So that I can access it in this manner :
            >pData->A = 56;
            >pData->data[pData->L - 1] = '\0';[/color]

            struct
            {
            char A;
            char L;
            char data[];
            } fred;

            struct fred *pData;

            [color=blue]
            >Now I want to represent
            >+---+---+-----------+---+
            >| A | L | D A T A | B |
            >+---+---+-----------+---+
            >
            >where B - is some data ( 1 byte)
            >I want to access it like this
            >pData->B
            >(Remember it is after variable length data)
            >
            >How can I do it....????[/color]

            You can't by name. The struct hack^W^W flexible array member has to be
            the last member of the structure.

            pData->data[ pData->L ] points to B.


            --
            #include <standard.discl aimer>
            _
            Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
            Per the FCA, this address may not be added to any commercial mail list

            Comment

            • Old Wolf

              #7
              Re: variable length record using struct/union - help

              > Now I want to represent[color=blue]
              > +---+---+-----------+---+
              > | A | L | D A T A | B |
              > +---+---+-----------+---+
              >
              > where B - is some data ( 1 byte)
              > I want to access it like this
              > pData->B
              > (Remember it is after variable length data)
              >
              > How can I do it....????
              >
              > -Neo[/color]

              typedef unsigned char *NEO_PTR;
              #define NEO_A(np) ((np)[0])
              #define NEO_L(np) ((np)[1])
              #define NEO_DATA(np) ((np) + 2)
              #define NEO_DATA_END(np ) (NEO_DATA(np) + NEO_L(np))
              #define NEO_B(np) (NEO_DATA_END(n p)[0])

              You can't access with the pointer syntax as you described.
              Also, remember that these are macros so don't go "++" in them, etc.

              NEO_PTR np = somewhere;
              printf("B=%d, L=%d, A=%d, data=%s",
              NEO_B(np), NEO_L(np), NEO_A(np), NEO_DATA(np));
              NEO_B(np) = 15;

              Comment

              • Jack Klein

                #8
                Re: variable length record using struct/union - help

                On Mon, 02 Feb 2004 14:37:14 GMT, "xarax" <xarax@email.co m> wrote in
                comp.lang.c:
                [color=blue]
                > "Panchal V" <vks_vikas@redi ffmail.com> wrote in message
                > news:13fbeb79.0 402020600.1afa8 655@posting.goo gle.com...[color=green]
                > > I want to access a variable length record in C, the format is as
                > > follows :
                > >
                > > +---+---+-----------+
                > > | A | L | D A T A |
                > > +---+---+-----------+
                > > A - Some Data (1 BYTE)
                > > L - Length the Data that follows (1 BYTE)
                > > then actual data
                > >
                > > I want to access and represent this record using struct/union in c,
                > > how can I do it...
                > > Data is variable length, L tell the length of data (in bytes) that
                > > follows...
                > > So that I can access it in this manner :
                > > pData->A = 56;
                > > pData->data[pData->L - 1] = '\0';
                > >
                > >
                > >
                > > Now I want to represent
                > > +---+---+-----------+---+
                > > | A | L | D A T A | B |
                > > +---+---+-----------+---+
                > >
                > > where B - is some data ( 1 byte)
                > > I want to access it like this
                > > pData->B
                > > (Remember it is after variable length data)
                > >
                > > How can I do it....????[/color]
                >
                > =============== =============== =
                > /* Use the "struct hack" approach. */[/color]

                No, don't, it's undefined behavior.

                --
                Jack Klein
                Home: http://JK-Technology.Com
                FAQs for
                comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
                comp.lang.c++ http://www.parashift.com/c++-faq-lite/
                alt.comp.lang.l earn.c-c++

                Comment

                • Panchal V

                  #9
                  Re: variable length record using struct/union - help

                  oldwolf@inspire .net.nz (Old Wolf) wrote in message news:<843a4f78. 0402021446.1bd8 c394@posting.go ogle.com>...[color=blue][color=green]
                  > > Now I want to represent
                  > > +---+---+-----------+---+
                  > > | A | L | D A T A | B |
                  > > +---+---+-----------+---+
                  > >
                  > > where B - is some data ( 1 byte)
                  > > I want to access it like this
                  > > pData->B
                  > > (Remember it is after variable length data)
                  > >
                  > > How can I do it....????
                  > >
                  > > -Neo[/color]
                  >
                  > typedef unsigned char *NEO_PTR;
                  > #define NEO_A(np) ((np)[0])
                  > #define NEO_L(np) ((np)[1])
                  > #define NEO_DATA(np) ((np) + 2)
                  > #define NEO_DATA_END(np ) (NEO_DATA(np) + NEO_L(np))
                  > #define NEO_B(np) (NEO_DATA_END(n p)[0])
                  >
                  > You can't access with the pointer syntax as you described.
                  > Also, remember that these are macros so don't go "++" in them, etc.
                  >
                  > NEO_PTR np = somewhere;
                  > printf("B=%d, L=%d, A=%d, data=%s",
                  > NEO_B(np), NEO_L(np), NEO_A(np), NEO_DATA(np));
                  > NEO_B(np) = 15;[/color]

                  This approach seems to be good as compared to other hacks... if
                  side-effects are taken care of (sequence points) etc.

                  Thanks for your views...

                  - Neo

                  Comment

                  • Panchal V

                    #10
                    Re: variable length record using struct/union - help

                    Jack Klein <jackklein@spam cop.net> wrote in message news:<eu6u109k2 84mnj2jbcmtd9ls rklr8t2431@4ax. com>...[color=blue]
                    > On Mon, 02 Feb 2004 14:37:14 GMT, "xarax" <xarax@email.co m> wrote in
                    > comp.lang.c:
                    >[color=green]
                    > > "Panchal V" <vks_vikas@redi ffmail.com> wrote in message
                    > > news:13fbeb79.0 402020600.1afa8 655@posting.goo gle.com...[color=darkred]
                    > > > I want to access a variable length record in C, the format is as
                    > > > follows :
                    > > >
                    > > > +---+---+-----------+
                    > > > | A | L | D A T A |
                    > > > +---+---+-----------+
                    > > > A - Some Data (1 BYTE)
                    > > > L - Length the Data that follows (1 BYTE)
                    > > > then actual data
                    > > >
                    > > > I want to access and represent this record using struct/union in c,
                    > > > how can I do it...
                    > > > Data is variable length, L tell the length of data (in bytes) that
                    > > > follows...
                    > > > So that I can access it in this manner :
                    > > > pData->A = 56;
                    > > > pData->data[pData->L - 1] = '\0';
                    > > >
                    > > >
                    > > >
                    > > > Now I want to represent
                    > > > +---+---+-----------+---+
                    > > > | A | L | D A T A | B |
                    > > > +---+---+-----------+---+
                    > > >
                    > > > where B - is some data ( 1 byte)
                    > > > I want to access it like this
                    > > > pData->B
                    > > > (Remember it is after variable length data)
                    > > >
                    > > > How can I do it....????[/color]
                    > >
                    > > =============== =============== =
                    > > /* Use the "struct hack" approach. */[/color]
                    >
                    > No, don't, it's undefined behavior.[/color]

                    What's undefined?

                    -Neo

                    Comment

                    • Panchal V

                      #11
                      Re: variable length record using struct/union - help

                      Kevin D. Quitt <KQuittUNMUNG@I EEIncUNMUNG.com > wrote in message news:<ct0t109b9 fkpljocer8h59ms fgumkhpq2d@4ax. com>...[color=blue]
                      > On 2 Feb 2004 06:00:01 -0800, vks_vikas@redif fmail.com (Panchal V) wrote:
                      >
                      >[color=green]
                      > >I want to access a variable length record in C, the format is as
                      > >follows :
                      > >
                      > >+---+---+-----------+
                      > >| A | L | D A T A |
                      > >+---+---+-----------+
                      > >A - Some Data (1 BYTE)
                      > >L - Length the Data that follows (1 BYTE)
                      > >then actual data
                      > >
                      > >I want to access and represent this record using struct/union in c,
                      > >how can I do it...
                      > >Data is variable length, L tell the length of data (in bytes) that
                      > >follows...
                      > >So that I can access it in this manner :
                      > >pData->A = 56;
                      > >pData->data[pData->L - 1] = '\0';[/color]
                      >
                      > struct
                      > {
                      > char A;
                      > char L;
                      > char data[];
                      > } fred;
                      >
                      > struct fred *pData;
                      >
                      >[color=green]
                      > >Now I want to represent
                      > >+---+---+-----------+---+
                      > >| A | L | D A T A | B |
                      > >+---+---+-----------+---+
                      > >
                      > >where B - is some data ( 1 byte)
                      > >I want to access it like this
                      > >pData->B
                      > >(Remember it is after variable length data)
                      > >
                      > >How can I do it....????[/color]
                      >
                      > You can't by name. The struct hack^W^W flexible array member has to be
                      > the last member of the structure.
                      >
                      > pData->data[ pData->L ] points to B.[/color]

                      char data[];
                      This doesn't seem to work on All implementations (compilers)

                      I'm using c51 by KEIL, it reports unknown array size...

                      And lets say we define one more variable after it, compiler starts
                      complaining, in GCC too...

                      -Neo

                      Comment

                      • Kevin D. Quitt

                        #12
                        Re: variable length record using struct/union - help

                        On Tue, 03 Feb 2004 03:56:21 GMT, Jack Klein <jackklein@spam cop.net>
                        wrote:[color=blue][color=green]
                        >> /* Use the "struct hack" approach. */[/color]
                        >
                        >No, don't, it's undefined behavior.[/color]

                        No, it isn't. It's part of C99, although they call it "flexible array
                        member".


                        --
                        #include <standard.discl aimer>
                        _
                        Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
                        Per the FCA, this address may not be added to any commercial mail list

                        Comment

                        • Kevin D. Quitt

                          #13
                          Re: variable length record using struct/union - help

                          On 3 Feb 2004 00:54:49 -0800, vks_vikas@redif fmail.com (Panchal V) wrote:

                          [color=blue]
                          >Kevin D. Quitt <KQuittUNMUNG@I EEIncUNMUNG.com > wrote in message news:<ct0t109b9 fkpljocer8h59ms fgumkhpq2d@4ax. com>...[color=green]
                          >> You can't by name. The struct hack^W^W flexible array member has to be
                          >> the last member of the structure.[/color]
                          >
                          > char data[];
                          >This doesn't seem to work on All implementations (compilers)
                          >
                          >I'm using c51 by KEIL, it reports unknown array size...[/color]

                          Then it's not a C99 compiler. Per the Standard, 6.7.2.1:

                          16 As a special case, the last element of a structure with more than one
                          named member may have an incomplete array type; this is called a flexible
                          array member. With two exceptions, the flexible array member is ignored.
                          First, the size of the structure shall be equal to the offset of the last
                          element of an otherwise identical structure that replaces the flexible
                          array member with an array of unspecified length.106) Second, when a . (or
                          ->) operator has a left operand that is (a pointer to) a structure with a
                          flexible array member and the right operand names that member, it behaves
                          as if that member were replaced with the longest array (with the same
                          element type) that would not make the structure larger than the object
                          being accessed; the offset of the array shall remain that of the flexible
                          array member, even if this would differ from that of the replacement
                          array. If this array would have no elements, it behaves as if it had one
                          element but the behavior is undefined if any attempt is made to access
                          that element or to generate a pointer one past it.


                          [color=blue]
                          >And lets say we define one more variable after it, compiler starts
                          >complaining, in GCC too...[/color]

                          Of course, because the flexible array member must be the last member.


                          --
                          #include <standard.discl aimer>
                          _
                          Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
                          Per the FCA, this address may not be added to any commercial mail list

                          Comment

                          • Richard Bos

                            #14
                            Re: variable length record using struct/union - help

                            Kevin D. Quitt <KQuittUNMUNG@I EEIncUNMUNG.com > wrote:
                            [color=blue]
                            > On Tue, 03 Feb 2004 03:56:21 GMT, Jack Klein <jackklein@spam cop.net>
                            > wrote:[color=green][color=darkred]
                            > >> /* Use the "struct hack" approach. */[/color]
                            > >
                            > >No, don't, it's undefined behavior.[/color]
                            >
                            > No, it isn't. It's part of C99, although they call it "flexible array
                            > member".[/color]

                            But what xanax (to whom Jack Klein replied) demonstrated wasn't a C99
                            flexible array member, but a C89 mini-array-and-malloc struct hack. And
                            that _is_ undefined.

                            Richard

                            Comment

                            • Kevin D. Quitt

                              #15
                              Re: variable length record using struct/union - help

                              On Tue, 03 Feb 2004 16:08:41 GMT, rlb@hoekstra-uitgeverij.nl (Richard Bos)
                              wrote:[color=blue]
                              >But what xanax (to whom Jack Klein replied) demonstrated wasn't a C99
                              >flexible array member, but a C89 mini-array-and-malloc struct hack. And
                              >that _is_ undefined.[/color]

                              Indeed - my bad.

                              --
                              #include <standard.discl aimer>
                              _
                              Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
                              Per the FCA, this address may not be added to any commercial mail list

                              Comment

                              Working...