Array in struct

Discussion in 'C Programming' started by Jan Danielsson, Aug 19, 2005.

  1. Hello all,

    I'm writing an XML parser, and I'd like to know how portable a
    solution is.

    When I pass an STag or EmptyElement tag to the application, I
    (obviously) need to pass the attribute list somehow. I thought about
    storing the list in something like this:

    typedef struct _ATTRLIST
    {
    int numAttr;
    ATTR attr[1];
    }ATTRLIST, *PATTRLIST;

    foo()
    {
    PATTRLIST pal = 0;
    ...blah...
    if(nAttr > 0)
    {
    pal = malloc(sizeof(ATTRLIST)+(nAttr-1)*sizeof(ATTR))
    ...blah...
    }
    }

    Now, what I'm worried about is portability. Is using an 1-sized array
    like that a bad move? Does C guarantee that structure members are ordered?

    Thankful for any advice.

    --
    Kind Regards,
    Jan Danielsson
    Te audire no possum. Musa sapientum fixa est in aure.
    Jan Danielsson, Aug 19, 2005
    #1
    1. Advertising

  2. Jan Danielsson wrote:

    > I'm writing an XML parser, and I'd like to know how portable a
    > solution is.
    >
    > When I pass an STag or EmptyElement tag to the application, I
    > (obviously) need to pass the attribute list somehow. I thought about
    > storing the list in something like this:
    >
    > typedef struct _ATTRLIST
    > {
    > int numAttr;
    > ATTR attr[1];
    > }ATTRLIST, *PATTRLIST;
    >
    > foo()
    > {
    > PATTRLIST pal = 0;
    > ...blah...
    > if(nAttr > 0)
    > {
    > pal = malloc(sizeof(ATTRLIST)+(nAttr-1)*sizeof(ATTR))
    > ...blah...
    > }
    > }
    >
    > Now, what I'm worried about is portability. Is using an 1-sized array
    > like that a bad move?


    from the FAQ:-
    FAQ 2.6 "I came across some code that declared a structure with the
    last member an array of one element, and then did some tricky
    allocation to make it act like the array had several elements. Is this
    legal or portable?"

    It seems to be technically illegal but works on all known
    implementations... You could pass two parameters a count and an array
    of
    attributes.


    > Does C guarantee that structure members are ordered?


    yes.

    <snip>


    --
    Nick Keighley

    We recommend, rather, that users take advantage of the extensions of
    GNU C and disregard the limitations of other compilers. Aside from
    certain supercomputers and obsolete small machines, there is less
    and less reason ever to use any other C compiler other than for
    bootstrapping GNU CC.
    (Using and Porting GNU CC)
    Nick Keighley, Aug 19, 2005
    #2
    1. Advertising

  3. Jan Danielsson wrote:
    [...]
    > typedef struct _ATTRLIST
    > {
    > int numAttr;
    > ATTR attr[1];
    > }ATTRLIST, *PATTRLIST;
    >
    > foo()
    > {
    > PATTRLIST pal = 0;
    > ...blah...
    > if(nAttr > 0)
    > {
    > pal = malloc(sizeof(ATTRLIST)+(nAttr-1)*sizeof(ATTR))
    > ...blah...
    > }
    > }
    >
    > Now, what I'm worried about is portability. Is using an 1-sized array
    > like that a bad move? Does C guarantee that structure members are ordered?

    [...]

    As someone else pointed out, the FAQ says it's "technically illegal",
    but it "works on all known implementations".

    You could get around this, if you want to not worry about it, by using
    something like:

    typedef struct _ATTRLIST
    {
    int numAttr;
    ATTR *attr;
    }
    ATTRLIST, *PATTRLIST;

    ...
    pal = malloc(sizeof(ATTRLIST));
    if ( pal != NULL )
    {
    pal->attr = malloc(nAttr*sizeof(*pal->attr));
    ...

    You also have to remember to free pal->attr as well as pal.

    On the other hand, I do have to admit that I use the 1-element array
    version in numerous places, and have had no problems on all the
    various platforms I've ported to.

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Aug 19, 2005
    #3
  4. Jan Danielsson sade:
    > Hello all,
    >
    > I'm writing an XML parser, and I'd like to know how portable a
    > solution is.
    >
    > When I pass an STag or EmptyElement tag to the application, I
    > (obviously) need to pass the attribute list somehow. I thought about
    > storing the list in something like this:
    >
    > typedef struct _ATTRLIST
    > {
    > int numAttr;
    > ATTR attr[1];
    > }ATTRLIST, *PATTRLIST;
    >
    > foo()
    > {
    > PATTRLIST pal = 0;
    > ...blah...
    > if(nAttr > 0)
    > {
    > pal = malloc(sizeof(ATTRLIST)+(nAttr-1)*sizeof(ATTR))
    > ...blah...
    > }
    > }
    >
    > Now, what I'm worried about is portability. Is using an 1-sized array
    > like that a bad move? Does C guarantee that structure members are ordered?
    >
    > Thankful for any advice.
    >


    The c99 standard provides a feature called a flexible array member which
    is a portable struct hack.

    typedef struct _ATTRLIST
    {
    int numAttr;
    ATTR attr[];
    } ATTRLIST, *PATTRLIST;

    PATTRLIST p = malloc(sizeof(ATTRLIST) + sizeof(ATTR) * 10);

    Tobias
    --
    IMPORTANT: The contents of this email and attachments are confidential
    and may be subject to legal privilege and/or protected by copyright.
    Copying or communicating any part of it to others is prohibited and may
    be unlawful.
    Tobias Blomkvist, Aug 19, 2005
    #4
  5. Jan Danielsson

    Eric Laberge Guest

    Tobias Blomkvist wrote:

    > The c99 standard provides a feature called a flexible array member which
    > is a portable struct hack.
    >
    > typedef struct _ATTRLIST
    > {
    > int numAttr;
    > ATTR attr[];
    > } ATTRLIST, *PATTRLIST;
    >
    > PATTRLIST p = malloc(sizeof(ATTRLIST) + sizeof(ATTR) * 10);
    >
    > Tobias


    Nice to know it is actually legal and portable! I've been using this a lot
    and never took the time to check if it was an OK construct or if it gave me
    the correct size for malloc.

    Where in the standard is this defined? I've decided to actually read the
    standard but am still in the beginnings of the document...

    --
    Eric Laberge
    Eric Laberge, Aug 19, 2005
    #5
  6. Eric Laberge sade:
    > Tobias Blomkvist wrote:
    >
    >
    >>The c99 standard provides a feature called a flexible array member which
    >>is a portable struct hack.
    >>
    >>typedef struct _ATTRLIST
    >>{
    >>int numAttr;
    >>ATTR attr[];
    >>} ATTRLIST, *PATTRLIST;
    >>
    >>PATTRLIST p = malloc(sizeof(ATTRLIST) + sizeof(ATTR) * 10);
    >>
    >>Tobias

    >
    >
    > Nice to know it is actually legal and portable! I've been using this a lot
    > and never took the time to check if it was an OK construct or if it gave me
    > the correct size for malloc.
    >
    > Where in the standard is this defined? I've decided to actually read the
    > standard but am still in the beginnings of the document...
    >


    Section 6.7.2.1

    Tobias
    --
    IMPORTANT: The contents of this email and attachments are confidential
    and may be subject to legal privilege and/or protected by copyright.
    Copying or communicating any part of it to others is prohibited and may
    be unlawful.
    Tobias Blomkvist, Aug 19, 2005
    #6
  7. Eric Laberge <> writes:
    > Tobias Blomkvist wrote:
    >
    >> The c99 standard provides a feature called a flexible array member which
    >> is a portable struct hack.
    >>
    >> typedef struct _ATTRLIST
    >> {
    >> int numAttr;
    >> ATTR attr[];
    >> } ATTRLIST, *PATTRLIST;
    >>
    >> PATTRLIST p = malloc(sizeof(ATTRLIST) + sizeof(ATTR) * 10);
    >>
    >> Tobias

    >
    > Nice to know it is actually legal and portable! I've been using this a lot
    > and never took the time to check if it was an OK construct or if it gave me
    > the correct size for malloc.
    >
    > Where in the standard is this defined? I've decided to actually read the
    > standard but am still in the beginnings of the document...


    For features defined in C99 but not in C90, "legal" does not
    necessarily imply "portable". The C99 standard is not univerally
    implemented.

    --
    Keith Thompson (The_Other_Keith) <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.
    Keith Thompson, Aug 19, 2005
    #7
  8. In article <>, Jan Danielsson <> writes:
    >
    > I'm writing an XML parser, and I'd like to know how portable a
    > solution is.
    >
    > When I pass an STag or EmptyElement tag to the application, I
    > (obviously) need to pass the attribute list somehow. I thought about
    > storing the list in something like this:
    >
    > typedef struct _ATTRLIST


    Others have already discussed the "struct hack", but note also that
    identifiers beginning with an underscore followed by an uppercase
    letter are always reserved to the implementation. You cannot
    portably use the struct tag "_ATTRLIST" for your own structure.
    Similarly, any identifier that begins with an underscore is reserved
    at file scope. Best bet: don't begin your identifiers with under-
    scores. C90 7.1.3.

    (Personally, I don't see why you use both a struct tag and a typedef,
    since the struct doesn't contain a pointer to the same struct type.
    My preference is to avoid typedef in nearly all situations, and
    particularly to not disguise a pointer type using typedef, but those
    are questions of style. Also, I avoid identifiers in block capitals;
    some like to reserve those for macro names, but I use mixed case for
    all identifiers as I've found that reduces the likelihood of name
    collisions in the environments where my code is typically compiled.
    That too is a style issue, of course.)

    --
    Michael Wojcik

    It does basically make you look fat and naked - but you see all this stuff.
    -- Susan Hallowell, TSA Security Lab Director, on "backscatter" scanners
    Michael Wojcik, Aug 20, 2005
    #8
    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. Chris Fogelklou
    Replies:
    36
    Views:
    1,335
    Chris Fogelklou
    Apr 20, 2004
  2. Daniel Rudy
    Replies:
    7
    Views:
    437
    Daniel Rudy
    Mar 31, 2006
  3. Replies:
    3
    Views:
    1,070
  4. TiloVillwock

    struct array within struct

    TiloVillwock, May 15, 2010, in forum: C Programming
    Replies:
    11
    Views:
    687
    Nick Keighley
    May 16, 2010
  5. Tuan  Bui
    Replies:
    14
    Views:
    452
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page