Is this some kind of hack

Discussion in 'C Programming' started by parag_paul, Dec 3, 2008.

  1. parag_paul

    parag_paul Guest

    The following structure is having a member
    fields which is a array of size 0 of char*

    #include <stdio.h>

    struct _table_model_entry {
    struct _table_model_entry *next;
    int line_nr;
    int nr_fields;
    char *fields[0]; /* User defined */
    };


    What is the use of such an array
     
    parag_paul, Dec 3, 2008
    #1
    1. Advertisements

  2. parag_paul

    viza Guest

    Hi

    It is not allowed in strict C but some compilers allow it as an extension.

    It usually means that after the nr_fields member there are some character
    pointers, and how many of them there is depends on some other datum. In
    this case it looks like that is just nr_fields, but in other cases the
    array might be null terminated.

    Suppose nr_fields was 3, then the struct would behave as if that 0 were a
    3.

    The problem you get is that you can't have an array of these structs, and
    the sizeof them isn't correct.

    HTH
    viza
     
    viza, Dec 3, 2008
    #2
    1. Advertisements

  3. parag_paul

    Guest Guest

    a bad idea. If you use a size of 1 you are using something
    called "the struct hack" which is technically wrong but in
    practice almost always works.
    somthing like this

    #include <stdio.h>

    #define FIELD_SIZE 4

    struct table_model_entry
    {
    struct _table_model_entry *next;
    int line_nr;
    int nr_fields;
    char *fields[1];
    };

    int main (void)
    {
    struct table_model_entry *tmptr;
    int field_count;
    scanf("%d", &field_count);
    tmptr = malloc (sizeof(*tmptr) - 1 + field_count * FIELD_SIZE);
    tmptr->next = NULL;
    tmptr->line_nr = 0;
    tmptr->nr_fields = field_count;
    return 0;
    }

    the number of fields and hence the size of the structure isn't
    determined
    until run time.
     
    Guest, Dec 3, 2008
    #3
  4. parag_paul

    James Kuyper Guest

    Please note that names starting with '_' are reserved for use by the
    implementation at file scope. If this struct type is defined by the
    implementation, you can use it, but you should not define it. If it is a
    struct defined in user code, you should change the name to one which is
    not reserved.

    Some people get in the habit of using such names because they see such
    names used in standard header files. Break that habit: only the
    implementation can define such names at file scope.

    You can use such names at block scope, but it's safer to avoid such
    names completely.
    This is one of three ways to do the same thing. This way works on
    certain compilers, but only as a non-conforming extension.

    The other way involves declaring an array of length 1, but using it as
    if it were a longer array. This has undefined behavior, but if you
    allocate sufficient memory to hold that longer array, on most (possibly
    all) C90 compilers, it will work as intended.

    The third way was added in C99. This involves leaving the array length
    unspecified, creating what in C99 is called a "flexible array member".

    Regardless of which approach you use, this can only be done on the very
    last member of a struct. The only practical way to create a struct of
    this type is in dynamically allocated memory. You could do so as follows:

    struct table_model_entry tme = malloc((sizeof tme)
    + (number_of_fields-1) * sizeof tme->fields[0]);

    Note that the '-1' is needed only if you use the fields[1], because in
    that case (sizeof tme) includes enough space to store one field.
    approach. It is unnecessary if you declare fields[0] or fields[].
     
    James Kuyper, Dec 3, 2008
    #4
  5. See question 2.6 of the comp.lang.c FAQ, <http://www.c-faq.com/>.
     
    Keith Thompson, Dec 3, 2008
    #5
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.