Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

variable length structures in C90

Tags:

c

gcc

c89

Zero-length arrays are allowed in GNU C. and can be initialized thus

struct line {
       int length;
       char contents[0];
     };

     struct line *thisline = (struct line *)
       malloc (sizeof (struct line) + this_length);
     thisline->length = this_length;

Note: I am referring to this page here: http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html (provides a basic intro to variable length structures in C)

It goes on to say: "In ISO C90, you would have to give contents a length of 1, which means either you waste space or complicate the argument to malloc."

What does that mean? Could someone provide an example of how you can initialize variable length structs in C90 to aid understanding?

like image 467
krisharav Avatar asked Jul 07 '26 00:07

krisharav


1 Answers

If you really have to use c90 then the C FAQ has this covered in Question 2.6 :

struct name {
int namelen;
char namestr[1];
};

struct name *ret =
    malloc(sizeof(struct name)-1 + strlen(newname)+1);
            /* -1 for initial [1]; +1 for \0 */

Although the FAQ does say:

It's not clear if it's legal or portable, but it is rather popular. An implementation of the technique might look something like this.

Although the gcc document basically says they support it, in C99 as the FAQ says they added flexible array members, which I cover in this answer which is covered in section 6.7.2.1 Structure and union specifiers and has the following example, which unlike the C90 example does not require special math to account for the size of the array:

EXAMPLE After the declaration:

   struct s { int n; double d[]; };

the structure struct s has a flexible array member d. A typical way to use this
is:

    int m = /* some value */;
    struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

and assuming that the call to malloc succeeds, the object pointed to by p
behaves, for most purposes, as if p had been declared as:

     struct { int n; double d[m]; } *p;

(there are circumstances in which this equivalence is broken; in particular, the
 offsets of member d might not be the same).
like image 200
Shafik Yaghmour Avatar answered Jul 08 '26 19:07

Shafik Yaghmour



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!