Zero length array declaration

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

    Zero length array declaration

    Hi,

    Looking to see if the following construct is valid:
    typedef struct {
    int foo;
    char bar[0];
    } foobar;

    Basically, the idea is to have the structure above point to a message
    buffer that has a 4-byte integer followed by a stream of variable
    number of bytes. The structure member "bar" is used to reference the
    stream of bytes. The above code compiles fine with a GNU based PPC
    cross-compiler running on Solaris and seems to do the function
    intended.

    My question is: Is it legal to declare an array with zero length? Or
    should bar have been declared to be at least one element in length?

    Comments appreciated.

    RS
  • Eric Sosman

    #2
    Re: Zero length array declaration

    RS wrote:[color=blue]
    > Hi,
    >
    > Looking to see if the following construct is valid:
    > typedef struct {
    > int foo;
    > char bar[0];
    > } foobar;
    >
    > Basically, the idea is to have the structure above point to a message
    > buffer that has a 4-byte integer followed by a stream of variable
    > number of bytes. The structure member "bar" is used to reference the
    > stream of bytes. The above code compiles fine with a GNU based PPC
    > cross-compiler running on Solaris and seems to do the function
    > intended.
    >
    > My question is: Is it legal to declare an array with zero length? Or
    > should bar have been declared to be at least one element in length?[/color]

    The construct as written is not legal C under either
    version of the Standard, although some compilers may allow
    it as an extension to the language.

    Declaring `bar' as a one-element array is and always has
    been legal. However, allocating extra memory for the struct
    and then using `bar' as if it had more than one element is
    not. This particular abuse (known as "the struct hack") works
    on the great majority of C implementations , but is not actually
    legitimate.

    The latest "C99" version of the Standard legitimizes the
    struct hack, but introduces a new syntax: you declare `bar'
    with no array size at all, as `char bar[]'. However, this is
    still relatively new and not yet widely supported by available
    compilers.

    --
    Eric.Sosman@sun .com

    Comment

    • jjr2004a

      #3
      Re: Zero length array declaration

      > Hi,[color=blue]
      >
      > Looking to see if the following construct is valid:
      > typedef struct {
      > int foo;
      > char bar[0];
      > } foobar;
      >[/color]
      I not sure about the legality of this - others can answer that.

      For the stated purpose this is wrong.

      char bar[0] should be char *bar instead. That's what a
      pointer is for - to refer or point to some storage located
      somewhere else.

      Comment

      • Keith Thompson

        #4
        Re: Zero length array declaration

        jjr2004a@yahoo. com (jjr2004a) writes:[color=blue][color=green]
        >> Looking to see if the following construct is valid:
        >> typedef struct {
        >> int foo;
        >> char bar[0];
        >> } foobar;
        >>[/color]
        > I not sure about the legality of this - others can answer that.
        >
        > For the stated purpose this is wrong.
        >
        > char bar[0] should be char *bar instead. That's what a
        > pointer is for - to refer or point to some storage located
        > somewhere else.[/color]

        No, the point of declaring bar as an array is that the array (of some
        dynamic size) is stored within the struct itself. The structure is
        allocated by calling malloc with a size equal to the size of the
        structure itself plus the number of characters to be stored in the
        array. It's called the "struct hack"; it's commonly supported, and
        commonly used, but not strictly legal.

        Declaring "char *bar" is of course valid as well, but it's a different
        thing, requiring a separate memory allocation (and later deallocation)
        for the array.

        As others have said elsethread, C99 adds support for the struct hack,
        but with a new syntax.

        --
        Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
        San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
        We must do something. This is something. Therefore, we must do this.

        Comment

        • Method Man

          #5
          Re: Zero length array declaration


          "RS" <rs.naukri@gmai l.com> wrote in message
          news:7dff197e.0 412011149.27f66 041@posting.goo gle.com...[color=blue]
          > Hi,
          >
          > Looking to see if the following construct is valid:
          > typedef struct {
          > int foo;
          > char bar[0];
          > } foobar;
          >
          > Basically, the idea is to have the structure above point to a message
          > buffer that has a 4-byte integer followed by a stream of variable
          > number of bytes. The structure member "bar" is used to reference the
          > stream of bytes. The above code compiles fine with a GNU based PPC
          > cross-compiler running on Solaris and seems to do the function
          > intended.
          >
          > My question is: Is it legal to declare an array with zero length? Or
          > should bar have been declared to be at least one element in length?
          >
          > Comments appreciated.
          >
          > RS[/color]

          Strictly speaking, accessing an array beyond its bounds results in undefined
          behaviour according to the Standard.


          Comment

          • Keith Thompson

            #6
            Re: Zero length array declaration

            "Method Man" <a@b.c> writes:[color=blue]
            > "RS" <rs.naukri@gmai l.com> wrote in message
            > news:7dff197e.0 412011149.27f66 041@posting.goo gle.com...[color=green]
            >> Hi,
            >>
            >> Looking to see if the following construct is valid:
            >> typedef struct {
            >> int foo;
            >> char bar[0];
            >> } foobar;
            >>
            >> Basically, the idea is to have the structure above point to a message
            >> buffer that has a 4-byte integer followed by a stream of variable
            >> number of bytes. The structure member "bar" is used to reference the
            >> stream of bytes. The above code compiles fine with a GNU based PPC
            >> cross-compiler running on Solaris and seems to do the function
            >> intended.
            >>
            >> My question is: Is it legal to declare an array with zero length? Or
            >> should bar have been declared to be at least one element in length?
            >>
            >> Comments appreciated.
            >>
            >> RS[/color]
            >
            > Strictly speaking, accessing an array beyond its bounds results in undefined
            > behaviour according to the Standard.[/color]

            Strictly speaking, declaring a 0-sized array is illegal. Some
            compilers may let you get away with it. Compilers that disallow
            0-sized arrays may let you implement the struct hack with
            char bar[1];
            The declaration is legal, but accessing elements beyond bar[0] invokes
            undefined behavior (which, if you've allocated enough memory, is
            likely to work aryway).

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
            San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
            We must do something. This is something. Therefore, we must do this.

            Comment

            • Mabden

              #7
              Re: Zero length array declaration

              "Keith Thompson" <kst-u@mib.org> wrote in message
              news:lnpt1tbh9v .fsf@nuthaus.mi b.org...[color=blue]
              > "Method Man" <a@b.c> writes:[color=green]
              > > "RS" <rs.naukri@gmai l.com> wrote in message
              > > news:7dff197e.0 412011149.27f66 041@posting.goo gle.com...[color=darkred]
              > >> Hi,
              > >>
              > >> Looking to see if the following construct is valid:
              > >> typedef struct {
              > >> int foo;
              > >> char bar[0];
              > >> } foobar;
              > >>
              > >> Basically, the idea is to have the structure above point to a[/color][/color][/color]
              message[color=blue][color=green][color=darkred]
              > >> buffer that has a 4-byte integer followed by a stream of variable
              > >> number of bytes. The structure member "bar" is used to reference[/color][/color][/color]
              the[color=blue][color=green][color=darkred]
              > >> stream of bytes. The above code compiles fine with a GNU based PPC
              > >> cross-compiler running on Solaris and seems to do the function
              > >> intended.[/color][/color][/color]

              If you want "to have the structure above point to a message buffer", you
              should use a pointer to a buffer containing a message. This buffer could
              be an array of strings, for instance.
              [color=blue][color=green][color=darkred]
              > >> My question is: Is it legal to declare an array with zero length?[/color][/color][/color]
              Or[color=blue][color=green][color=darkred]
              > >> should bar have been declared to be at least one element in length?
              > >>[/color]
              > >
              > > Strictly speaking, accessing an array beyond its bounds results in[/color][/color]
              undefined[color=blue][color=green]
              > > behaviour according to the Standard.[/color]
              >
              > Strictly speaking, declaring a 0-sized array is illegal. Some
              > compilers may let you get away with it. Compilers that disallow
              > 0-sized arrays may let you implement the struct hack with
              > char bar[1];
              > The declaration is legal, but accessing elements beyond bar[0] invokes
              > undefined behavior (which, if you've allocated enough memory, is
              > likely to work aryway).[/color]

              Especially if "aryway" means "not very well". I don't understand why you
              would even pursue such a line of reasoning when all the OP wants (read:
              needs) is to use a pointer. His post indicated what he wanted, so why go
              off on unsupported tangents that imply acceptance for arrays of zero
              length or whatever. It's a silly thing to run a thread on.

              --
              Mabden


              Comment

              • Flash Gordon

                #8
                Re: Zero length array declaration

                On Thu, 02 Dec 2004 02:38:56 GMT
                "Mabden" <mabden@sbc_glo bal.net> wrote:
                [color=blue]
                > "Keith Thompson" <kst-u@mib.org> wrote in message
                > news:lnpt1tbh9v .fsf@nuthaus.mi b.org...[color=green]
                > > "Method Man" <a@b.c> writes:[color=darkred]
                > > > "RS" <rs.naukri@gmai l.com> wrote in message
                > > > news:7dff197e.0 412011149.27f66 041@posting.goo gle.com...
                > > >> Hi,
                > > >>
                > > >> Looking to see if the following construct is valid:
                > > >> typedef struct {
                > > >> int foo;
                > > >> char bar[0];
                > > >> } foobar;
                > > >>
                > > >> Basically, the idea is to have the structure above point to a[/color][/color]
                > message[color=green][color=darkred]
                > > >> buffer that has a 4-byte integer followed by a stream of variable
                > > >> number of bytes. The structure member "bar" is used to reference[/color][/color]
                > the[color=green][color=darkred]
                > > >> stream of bytes. The above code compiles fine with a GNU based
                > > >PPC> cross-compiler running on Solaris and seems to do the function
                > > >> intended.[/color][/color]
                >
                > If you want "to have the structure above point to a message buffer",
                > you should use a pointer to a buffer containing a message. This buffer
                > could be an array of strings, for instance.[/color]

                He does *not* want the structure to point to a buffer containing the
                message. The int foo is almost certainly part of the message comming
                over a communications link followed by a number of bytes. For instance,
                the bytes recieved might be
                int 5
                byte 1
                byte 2
                byte 3
                byte 4

                To do what you suggest the routine receiving this would first have to
                allocate memory for the "header" integer and a pointer, allocate another
                block for the rest of the message, set up the pointer and also change
                where it is sending the data to etc. Also, the entire lot might be
                comming in as one block of data so your solution could also meen copying
                the data around even more.
                [color=blue][color=green][color=darkred]
                > > >> My question is: Is it legal to declare an array with zero length?[/color][/color]
                > Or[color=green][color=darkred]
                > > >> should bar have been declared to be at least one element in
                > > >length?>
                > > >
                > > > Strictly speaking, accessing an array beyond its bounds results in[/color][/color]
                > undefined[color=green][color=darkred]
                > > > behaviour according to the Standard.[/color]
                > >
                > > Strictly speaking, declaring a 0-sized array is illegal. Some
                > > compilers may let you get away with it. Compilers that disallow
                > > 0-sized arrays may let you implement the struct hack with
                > > char bar[1];
                > > The declaration is legal, but accessing elements beyond bar[0]
                > > invokes undefined behavior (which, if you've allocated enough
                > > memory, is likely to work aryway).[/color]
                >
                > Especially if "aryway" means "not very well". I don't understand why
                > you would even pursue such a line of reasoning when all the OP wants
                > (read: needs) is to use a pointer. His post indicated what he wanted,
                > so why go off on unsupported tangents that imply acceptance for arrays
                > of zero length or whatever. It's a silly thing to run a thread on.[/color]

                No, Keith knows EXACTLY what he is tlking about and the OP was taking
                exactly the right approach. It is just unfortunate that the C89 standard
                did not bless a way of doing it and that the C99 standard did not
                include support for [0] and/or the [1] struct hack which had the benefit
                of existing practice.

                Also, although not covered by the ISO standard it is a very commonly
                supported extension. I would even go as far as to reject a compiler on
                the basis of it not supporting this and instead select one where it was
                supported, where it not for the fact I haven't come across a compiler
                where it fails.
                --
                Flash Gordon
                Living in interesting times.
                Although my email address says spam, it is real and I read it.

                Comment

                • Spiro Trikaliotis

                  #9
                  Re: Zero length array declaration

                  Hello,

                  Keith Thompson <kst-u@mib.org> wrote:
                  [color=blue]
                  > Declaring "char *bar" is of course valid as well, but it's a different
                  > thing, requiring a separate memory allocation (and later deallocation)
                  > for the array.[/color]

                  Well, a separate memory allocation is not needed. You can alloc
                  sizeof(struct) + extra bytes, and then have bar point to "after the
                  struct".

                  Or is there anything else in the standard that forbids this?

                  BTW: A good usage for now using a pointer is IMHO if you use shared
                  memory between processes, when the shared memory can be mapped to
                  different memory locations on every process. A pointer is quite useless
                  in this scenario, but some indices to the char bar[] array are not.

                  Regards,
                  Spiro.

                  --
                  Spiro R. Trikaliotis

                  Find top digital marketing resources from Vice Team SEO Agents. Get expert insights, strategies & tools to boost visibility, traffic, and online growth.

                  Comment

                  • Chris Croughton

                    #10
                    Re: Zero length array declaration

                    On Wed, 01 Dec 2004 16:13:28 -0500, Eric Sosman
                    <eric.sosman@su n.com> wrote:
                    [color=blue]
                    > Declaring `bar' as a one-element array is and always has
                    > been legal. However, allocating extra memory for the struct
                    > and then using `bar' as if it had more than one element is
                    > not. This particular abuse (known as "the struct hack") works
                    > on the great majority of C implementations , but is not actually
                    > legitimate.[/color]

                    How about (untested code):

                    typedef struct foo_s FooT;
                    struct foo_s
                    {
                    size_t size;
                    Foo *next;
                    };

                    char *fooAlloc(size_ t size)
                    {
                    FooT *s = malloc(sizeof(F ooT) + size);
                    if (!s)
                    {
                    do_error_handli ng();
                    }
                    s->size = size;
                    s->next = NULL; /* put it in a list or whatever */
                    return (char*) &s[1];
                    }

                    void fooFree(char *p)
                    {
                    FooT *s = (FooT*)(p - sizeof(FooT));
                    /* do whatever to the structure */
                    free(s);
                    }

                    The standard says that malloc() returns an area aligned for any purpose,
                    so assigning it to a FooT* is valid. By the definition of array access,
                    s[1] points to a valid address in the allocated memory beyond the
                    initial structure. Similarly, converting back for the free() is valid
                    (assuming that you've been passed a valid pointer, but that's true of
                    any allocation system).
                    [color=blue]
                    > The latest "C99" version of the Standard legitimizes the
                    > struct hack, but introduces a new syntax: you declare `bar'
                    > with no array size at all, as `char bar[]'. However, this is
                    > still relatively new and not yet widely supported by available
                    > compilers.[/color]

                    I don't think it's necessary (and is currently non-portable), since the
                    pointer to the 'extra' area can always be accessed by taking the address
                    of the next structure (or converting to char* and adding sizeof the
                    structure).

                    Chris C

                    Comment

                    • xarax

                      #11
                      Re: Zero length array declaration

                      "Chris Croughton" <chris@keristor .net> wrote in message
                      news:slrncquid6 .tuo.chris@ccse rver.keris.net. ..[color=blue]
                      > On Wed, 01 Dec 2004 16:13:28 -0500, Eric Sosman
                      > <eric.sosman@su n.com> wrote:
                      >[color=green]
                      > > Declaring `bar' as a one-element array is and always has
                      > > been legal. However, allocating extra memory for the struct
                      > > and then using `bar' as if it had more than one element is
                      > > not. This particular abuse (known as "the struct hack") works
                      > > on the great majority of C implementations , but is not actually
                      > > legitimate.[/color]
                      >
                      > How about (untested code):
                      >
                      > typedef struct foo_s FooT;
                      > struct foo_s
                      > {
                      > size_t size;
                      > Foo *next;[/color]

                      ITYM: FooT * next;
                      [color=blue]
                      > };
                      >
                      > char *fooAlloc(size_ t size)
                      > {
                      > FooT *s = malloc(sizeof(F ooT) + size);
                      > if (!s)
                      > {
                      > do_error_handli ng();
                      > }
                      > s->size = size;
                      > s->next = NULL; /* put it in a list or whatever */
                      > return (char*) &s[1];
                      > }
                      >
                      > void fooFree(char *p)
                      > {
                      > FooT *s = (FooT*)(p - sizeof(FooT));
                      > /* do whatever to the structure */
                      > free(s);
                      > }
                      >
                      > The standard says that malloc() returns an area aligned for any purpose,
                      > so assigning it to a FooT* is valid. By the definition of array access,
                      > s[1] points to a valid address in the allocated memory beyond the
                      > initial structure.[/color]

                      This is an incorrect assumption. The &s[1] is not necessarily
                      aligned to the largest size. The alignment of &s[1] is only
                      correctly aligned to the alignment of "struct foo_s", which
                      may be less than the largest alignment.

                      Suppose the largest legal alignment is 16, the sizeof(size_t)
                      is 4, and sizeof(FooT*) is 4. The sizeof(struct foo_s) is 8
                      and its alignment is 4. The &s[1] yields an 8-byte aligned,
                      but NOT 16-byte aligned pointer. Thus, you get undefined behavior.

                      [color=blue]
                      > Similarly, converting back for the free() is valid
                      > (assuming that you've been passed a valid pointer, but that's true of
                      > any allocation system).
                      >[color=green]
                      > > The latest "C99" version of the Standard legitimizes the
                      > > struct hack, but introduces a new syntax: you declare `bar'
                      > > with no array size at all, as `char bar[]'. However, this is
                      > > still relatively new and not yet widely supported by available
                      > > compilers.[/color]
                      >
                      > I don't think it's necessary (and is currently non-portable), since the
                      > pointer to the 'extra' area can always be accessed by taking the address
                      > of the next structure (or converting to char* and adding sizeof the
                      > structure).[/color]

                      Unless special care is taken to ensure that the total structure
                      alignment matches the largest alignment, you'll get undefined
                      behavior.


                      Comment

                      • Eric Sosman

                        #12
                        Re: Zero length array declaration

                        Chris Croughton wrote:[color=blue]
                        > On Wed, 01 Dec 2004 16:13:28 -0500, Eric Sosman
                        > <eric.sosman@su n.com> wrote:
                        >
                        >[color=green]
                        >> Declaring `bar' as a one-element array is and always has
                        >>been legal. However, allocating extra memory for the struct
                        >>and then using `bar' as if it had more than one element is
                        >>not. This particular abuse (known as "the struct hack") works
                        >>on the great majority of C implementations , but is not actually
                        >>legitimate.[/color]
                        >
                        >
                        > How about (untested code):
                        >
                        > typedef struct foo_s FooT;
                        > struct foo_s
                        > {
                        > size_t size;
                        > Foo *next;[/color]

                        ITYM `FooT' here.
                        [color=blue]
                        > };
                        >
                        > char *fooAlloc(size_ t size)
                        > {
                        > FooT *s = malloc(sizeof(F ooT) + size);[/color]

                        `sizeof *s + size' would be slightly better, but
                        does the same thing.
                        [color=blue]
                        > if (!s)
                        > {
                        > do_error_handli ng();
                        > }
                        > s->size = size;
                        > s->next = NULL; /* put it in a list or whatever */
                        > return (char*) &s[1];[/color]

                        When I use this trick, I usually write `(char*)(s + 1)',
                        which means exactly the same thing but (I think) makes my
                        intention just a tiny bit clearer to the reader. IMHO.
                        [color=blue]
                        > }
                        >
                        > void fooFree(char *p)
                        > {
                        > FooT *s = (FooT*)(p - sizeof(FooT));
                        > /* do whatever to the structure */
                        > free(s);
                        > }
                        >
                        > The standard says that malloc() returns an area aligned for any purpose,
                        > so assigning it to a FooT* is valid. By the definition of array access,
                        > s[1] points to a valid address in the allocated memory beyond the
                        > initial structure. Similarly, converting back for the free() is valid
                        > (assuming that you've been passed a valid pointer, but that's true of
                        > any allocation system).[/color]

                        Sure -- but there's no array at all in this code,
                        and it isn't "the struct hack." You're achieving the
                        same memory layout the hack aims for, but you've lost
                        the syntactic convenience of being able to refer to
                        the extra space as if it were a struct element. I use
                        this technique fairly commonly when there's a string
                        of some sort associated with the struct, but to reclaim
                        the syntactic sugar I go ahead and "waste" a `char*'
                        struct element pointing to the string that immediately
                        follows the struct itself.

                        Note that trafficking in the "midpoint pointer" instead
                        of in the pointer to the `FooT' itself is an orthogonal
                        matter. It's legal, it works, but it gives up *all* chance
                        of accessing the other struct members conveniently. I don't
                        see much point to it.
                        [color=blue][color=green]
                        >> The latest "C99" version of the Standard legitimizes the
                        >>struct hack, but introduces a new syntax: you declare `bar'
                        >>with no array size at all, as `char bar[]'. However, this is
                        >>still relatively new and not yet widely supported by available
                        >>compilers.[/color]
                        >
                        > I don't think it's necessary (and is currently non-portable), since the
                        > pointer to the 'extra' area can always be accessed by taking the address
                        > of the next structure (or converting to char* and adding sizeof the
                        > structure).[/color]

                        Yes, and if your tolerance for ugliness is high enough you
                        can even extend the technique to handle "extra" data of a type
                        with stricter alignment requirements than `char'. C99's "struct
                        un-hack" lets you achieve the same effect without all the grunge
                        *and* retains the syntactic convenience of letting you refer to
                        the "extra" data as part of the struct. I think that's worth
                        while; code that's easier to read is code that's less likely to
                        be written wrongly.

                        --
                        Eric.Sosman@sun .com

                        Comment

                        • Chris Croughton

                          #13
                          Re: Zero length array declaration

                          On Thu, 02 Dec 2004 17:44:12 GMT, xarax
                          <xarax@email.co m> wrote:
                          [color=blue]
                          > "Chris Croughton" <chris@keristor .net> wrote in message
                          > news:slrncquid6 .tuo.chris@ccse rver.keris.net. ..[color=green]
                          >>
                          >> Foo *next;[/color]
                          >
                          > ITYM: FooT * next;[/color]

                          Yup. I said it was untested (typing rather than copying).
                          [color=blue][color=green]
                          >> The standard says that malloc() returns an area aligned for any purpose,
                          >> so assigning it to a FooT* is valid. By the definition of array access,
                          >> s[1] points to a valid address in the allocated memory beyond the
                          >> initial structure.[/color]
                          >
                          > This is an incorrect assumption. The &s[1] is not necessarily
                          > aligned to the largest size. The alignment of &s[1] is only
                          > correctly aligned to the alignment of "struct foo_s", which
                          > may be less than the largest alignment.[/color]

                          Read what I said. I did not say that it was aligned to the "largest
                          size". If you look at the code, it only needs to be aligned to a char,
                          and all other types are at least as big as a char.
                          [color=blue]
                          > Suppose the largest legal alignment is 16, the sizeof(size_t)
                          > is 4, and sizeof(FooT*) is 4. The sizeof(struct foo_s) is 8
                          > and its alignment is 4. The &s[1] yields an 8-byte aligned,
                          > but NOT 16-byte aligned pointer. Thus, you get undefined behavior.[/color]

                          And sizeof(char) is 1 (by definition). It's not undefined at all,
                          since nothing can have a sizeof less than 1 (although they may all be
                          equal to 1).
                          [color=blue]
                          > Unless special care is taken to ensure that the total structure
                          > alignment matches the largest alignment, you'll get undefined
                          > behavior.[/color]

                          No, only to the largest alignment needed. In this case, the smallest
                          alignment will do. But it's easy enough to align to all of the built-in
                          types, just make a union with all of the largest types (intmax_t, a
                          pointer, and long double will do), and round up to the next multiple of
                          that bigger than the size of the structure.

                          Chris C

                          Comment

                          • jacob navia

                            #14
                            Re: Zero length array declaration

                            RS wrote:[color=blue]
                            > Hi,
                            >
                            > Looking to see if the following construct is valid:
                            > typedef struct {
                            > int foo;
                            > char bar[0];
                            > } foobar;
                            >
                            > Basically, the idea is to have the structure above point to a message
                            > buffer that has a 4-byte integer followed by a stream of variable
                            > number of bytes. The structure member "bar" is used to reference the
                            > stream of bytes. The above code compiles fine with a GNU based PPC
                            > cross-compiler running on Solaris and seems to do the function
                            > intended.
                            >
                            > My question is: Is it legal to declare an array with zero length? Or
                            > should bar have been declared to be at least one element in length?
                            >
                            > Comments appreciated.
                            >
                            > RS[/color]

                            The correct declaration in C99 is:

                            typedef struct {
                            int foo;
                            char bar[];
                            } foobar;

                            This will work as intended in any C99 compiler

                            sizeof(foobar) == sizeof(int);

                            allocate with
                            foobar *foo = malloc(sizeof(f oobar)+25);
                            to allocate a "foobar" followed by 25 characters.

                            jacob

                            Comment

                            • Eric Sosman

                              #15
                              Re: Zero length array declaration

                              jacob navia wrote:[color=blue]
                              > RS wrote:
                              >[color=green]
                              >>Hi,
                              >>
                              >>Looking to see if the following construct is valid:
                              >>typedef struct {
                              >> int foo;
                              >> char bar[0];
                              >>} foobar;
                              >>
                              >>Basically, the idea is to have the structure above point to a message
                              >>buffer that has a 4-byte integer followed by a stream of variable
                              >>number of bytes. The structure member "bar" is used to reference the
                              >>stream of bytes. The above code compiles fine with a GNU based PPC
                              >>cross-compiler running on Solaris and seems to do the function
                              >>intended.
                              >>
                              >>My question is: Is it legal to declare an array with zero length? Or
                              >>should bar have been declared to be at least one element in length?
                              >>
                              >>Comments appreciated.
                              >>
                              >>RS[/color]
                              >
                              >
                              > The correct declaration in C99 is:
                              >
                              > typedef struct {
                              > int foo;
                              > char bar[];
                              > } foobar;
                              >
                              > This will work as intended in any C99 compiler
                              >
                              > sizeof(foobar) == sizeof(int);[/color]

                              No; sizeof(foobar) >= sizeof(int) is all you can
                              be sure of. The compiler may insert padding between
                              the `foo' and `bar' members, even though there seems
                              no obvious reason to do so in this case.
                              [color=blue]
                              > allocate with
                              > foobar *foo = malloc(sizeof(f oobar)+25);
                              > to allocate a "foobar" followed by 25 characters.[/color]

                              malloc(sizeof *foo + 25) would be better.

                              --
                              Eric.Sosman@sun .com

                              Comment

                              Working...