Initializing an Array of Pointers to Structs

Discussion in 'C Programming' started by ccdrbrg, Apr 13, 2005.

  1. ccdrbrg

    ccdrbrg Guest

    I am trying to initialize an arrary of
    pointers to structs with constants.

    Sample code:

    struct mystruct {
    char *text;
    int number;
    };

    struct mystruct *array[] = {
    {"string1", 1},
    {"string2", 2},
    {"string3", 3},
    };

    GCC complains: "braces around scaler initializer"

    I would think {"string1", 1} would be
    replaced with an address upon compilation.

    For example,
    char *strings[] = {"string1", "string2", NULL};
    works.

    Any help would be appreciated.

    Chad
     
    ccdrbrg, Apr 13, 2005
    #1
    1. Advertisements

  2. ccdrbrg

    Eric Sosman Guest

    struct mystruct array_data[] = {
    { "string1", 1 },
    { "string2", 2 },
    { "string3", 3 },
    };

    struct mystruct *array[] = {
    &array_data[0], /* or `array_data + 0' */
    &array_data[1],
    &array_data[2],
    };
     
    Eric Sosman, Apr 13, 2005
    #2
    1. Advertisements

  3. ccdrbrg

    ccdrbrg Guest

    Is it possible to initialize the array without declaring
    an intermediate variable to get an address?

    Chad
     
    ccdrbrg, Apr 13, 2005
    #3
  4. ccdrbrg

    Eric Sosman Guest

    (See up-thread for snipped context: He wants to initialize
    an array of pointers to structs that are also initialized.)

    No. The string literal is the only C construct that
    creates and initializes an "anonymous" object. All other
    initialized objects must have names.
     
    Eric Sosman, Apr 13, 2005
    #4
  5. ccdrbrg

    Chris Torek Guest

    Except in C99, where compound literals create anonymous
    objects.

    For instance, in C99 (but not C89), one can write:

    /* tables for decoding SCSI <code,subcode> pairs */

    struct subcode {
    int sc_num;
    char *sc_msg;
    };
    struct code {
    int co_num;
    size_t co_nsub;
    struct subcode *co_subc;
    };

    struct code scsi_codetab[] = {
    {
    0, 2,
    (struct subcode [2]) {
    { 0, "0/0" },
    { 1, "0/1" },
    },
    },
    {
    1, 3,
    (struct subcode [3]) {
    { 0, "1/0" },
    { 27, "1/27" },
    { 40, "1/40" },
    }
    },
    };

    (The above is not intended to be particularly useful; in particular
    the code and subcode numbers are made up and the sc_msg strings are
    ridiculous. But SCSI does have code/subcode pairs and the overall
    technique itself is reasonable.)

    Note that even though you *can* do this in C99, it is probably
    better to use C89 constructs to match up the "number of subcodes"
    initializer (for co_nsub) and actual table sizes automatically.
    That is, writing this out "longhand" is actually less fragile:

    struct subcode {
    int sc_num;
    char *sc_msg;
    };
    struct code {
    int co_num;
    size_t co_nsub;
    struct subcode *co_subc;
    };

    static struct subcode sc0_table[] = {
    { 0, "0/0" },
    { 1, "0/1" },
    };
    static struct subcode sc1_table[] = {
    { 0, "1/0" },
    { 27, "1/27" },
    { 40, "1/40" },
    };
    #define COUNT_AND_TABLE(x) sizeof x / sizeof x[0], x
    struct code scsi_codetab[] = {
    { 0, COUNT_AND_TABLE(sc0_table) },
    { 1, COUNT_AND_TABLE(sc1_table) },
    };

    There is in fact a more general rule of programming that applies
    here: "if something is complex, give it a name."
     
    Chris Torek, Apr 13, 2005
    #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.