Odd char string initialization in structs

Discussion in 'C Programming' started by gustavo, Apr 27, 2006.

  1. gustavo

    gustavo Guest

    I was looking at the Sendmail's source code, and i've got confused
    about this kind of initialization:

    ------------------------
    struct prival PrivacyValues[] =
    {
    { "public", PRIV_PUBLIC },
    { "needmailhelo", PRIV_NEEDMAILHELO },
    { "needexpnhelo", PRIV_NEEDEXPNHELO },
    { "needvrfyhelo", PRIV_NEEDVRFYHELO },
    ....
    };
    ------------------------

    I'm familiar with char string[] = "foo", but i have no idea what the
    above snip of code is doing. Anyone could please explain?
     
    gustavo, Apr 27, 2006
    #1
    1. Advertising

  2. gustavo

    ciju Guest

    gustavo wrote:
    > I was looking at the Sendmail's source code, and i've got confused
    > about this kind of initialization:
    >
    > ------------------------
    > struct prival PrivacyValues[] =
    > {
    > { "public", PRIV_PUBLIC },
    > { "needmailhelo", PRIV_NEEDMAILHELO },
    > { "needexpnhelo", PRIV_NEEDEXPNHELO },
    > { "needvrfyhelo", PRIV_NEEDVRFYHELO },
    > ...
    > };
    > ------------------------
    >
    > I'm familiar with char string[] = "foo", but i have no idea what the
    > above snip of code is doing. Anyone could please explain?


    It is just the initialization of an array of structure.
    It can be done in another way in your code.

    Eg:
    PrivayValues[0].field1 = "public";
    PrivayValues[0].field2 = PRIV_PUBLIC;

    PrivayValues[1].field1 = "needmailhelo";
    PrivayValues[1].field2 = PRIV_NEEDMAILHELO;

    -----
    PrivayValues[n].field1 = "--";
    PrivayValues[n].field2 = --;
     
    ciju, Apr 27, 2006
    #2
    1. Advertising

  3. gustavo

    Kishore Yada Guest

    can you also provide what is struct prival..

    I suppose it must be

    struct prival
    {
    char *x;
    int y;
    };


    In the above case,
    one element of the struct can be created using

    struct prival OneElement = { "anystring", ANY_INTEGER };

    The first member might be confusing. What it does is
    1. Stores "anystring" into the string table.
    2. Puts a pointer in OneElement.x

    In a C program whereever string constants occur, they are replaced by
    pointers and the string constants are moved to the string table.

    But, array initialization is an exception to that.

    when we write string[] = "foo",
    the compiler actually takes it as

    string[4] = { 'f', 'o', 'o' , '\0' };

    and therefore "foo" does not go to the string table at all.


    Regards,
    Yada Kishore
     
    Kishore Yada, Apr 27, 2006
    #3
  4. gustavo

    Guest

    gustavo wrote:
    > I was looking at the Sendmail's source code, and i've got confused
    > about this kind of initialization:
    >
    > ------------------------
    > struct prival PrivacyValues[] =
    > {
    > { "public", PRIV_PUBLIC },
    > { "needmailhelo", PRIV_NEEDMAILHELO },
    > { "needexpnhelo", PRIV_NEEDEXPNHELO },
    > { "needvrfyhelo", PRIV_NEEDVRFYHELO },
    > ...
    > };
    > ------------------------
    >
    > I'm familiar with char string[] = "foo", but i have no idea what the
    > above snip of code is doing. Anyone could please explain?


    char string[] = "foo";

    is actually just a convenient shortcut of the more general form:

    char string[] = {
    'f' ,
    'o' ,
    'o' ,
    '\0'
    };

    The general form applies to all types in C, for example:

    int example[] = {
    100,
    200,
    300
    };

    this includes structs, for example:

    struct thing {
    char *name;
    int size;
    };

    struct thing stuff[] = {
    {"Me", 100},
    {"Myself", 200},
    {"I", 300}
    };
     
    , Apr 27, 2006
    #4
  5. gustavo

    ais523 Guest

    gustavo wrote:

    > I was looking at the Sendmail's source code, and i've got confused
    > about this kind of initialization:
    >
    > ------------------------
    > struct prival PrivacyValues[] =
    > {
    > { "public", PRIV_PUBLIC },
    > { "needmailhelo", PRIV_NEEDMAILHELO },
    > { "needexpnhelo", PRIV_NEEDEXPNHELO },
    > { "needvrfyhelo", PRIV_NEEDVRFYHELO },
    > ...
    > };
    > ------------------------
    >
    > I'm familiar with char string[] = "foo", but i have no idea what the
    > above snip of code is doing. Anyone could please explain?

    [The quote above is to identify the thread]

    After reading the responses to this thread, I started wondering whether
    the 'universal initialiser' {0} could apply to types like int which can
    be initialised normally. So I wrote the program

    #include <stdio.h>

    int i = {0};
    int j = {1};

    int main(void)
    {
    printf("%d %d\n",i,j);
    return 0;
    }

    which compiles on c89-conforming gcc with warnings turned up to the max
    with no diagnostics, printing
    0 1
    as expected. Is it really possible to initialise anything like this?
     
    ais523, Apr 27, 2006
    #5
  6. gustavo

    Flash Gordon Guest

    ais523 wrote:

    <snip>

    > After reading the responses to this thread, I started wondering whether
    > the 'universal initialiser' {0} could apply to types like int which can
    > be initialised normally. So I wrote the program
    >
    > #include <stdio.h>
    >
    > int i = {0};
    > int j = {1};
    >
    > int main(void)
    > {
    > printf("%d %d\n",i,j);
    > return 0;
    > }
    >
    > which compiles on c89-conforming gcc with warnings turned up to the max
    > with no diagnostics, printing
    > 0 1
    > as expected. Is it really possible to initialise anything like this?


    Yes, this is perfectly legal C and is defined as doing what you expect.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc

    Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
     
    Flash Gordon, Apr 27, 2006
    #6
  7. gustavo

    edware Guest

    Flash Gordon wrote:
    > ais523 wrote:
    >
    > <snip>
    >
    >> After reading the responses to this thread, I started wondering whether
    >> the 'universal initialiser' {0} could apply to types like int which can
    >> be initialised normally. So I wrote the program
    >>
    >> #include <stdio.h>
    >>
    >> int i = {0};
    >> int j = {1};
    >>
    >> int main(void)
    >> {
    >> printf("%d %d\n",i,j);
    >> return 0;
    >> }
    >>
    >> which compiles on c89-conforming gcc with warnings turned up to the max
    >> with no diagnostics, printing
    >> 0 1
    >> as expected. Is it really possible to initialise anything like this?

    >
    > Yes, this is perfectly legal C and is defined as doing what you expect.


    struct test_t {
    char *a;
    int b;
    double c;
    };

    int main(void)
    {
    struct test_t test = { 0 };
    }

    Will this initialization set the whole struct to 0,
    or just the first member, byte, or something like that?
     
    edware, Apr 27, 2006
    #7
  8. gustavo

    Default User Guest

    ciju wrote:

    >
    > gustavo wrote:
    > > I was looking at the Sendmail's source code, and i've got confused
    > > about this kind of initialization:
    > >
    > > ------------------------
    > > struct prival PrivacyValues[] =
    > > {
    > > { "public", PRIV_PUBLIC },
    > > { "needmailhelo", PRIV_NEEDMAILHELO },
    > > { "needexpnhelo", PRIV_NEEDEXPNHELO },
    > > { "needvrfyhelo", PRIV_NEEDVRFYHELO },
    > > ...
    > > };
    > > ------------------------
    > >
    > > I'm familiar with char string[] = "foo", but i have no idea what the
    > > above snip of code is doing. Anyone could please explain?

    >
    > It is just the initialization of an array of structure.
    > It can be done in another way in your code.
    >
    > Eg:
    > PrivayValues[0].field1 = "public";
    > PrivayValues[0].field2 = PRIV_PUBLIC;


    This is not the same thing at all. You have assignment, not
    initialization. If field1 happens to be an array of char rather than a
    pointer to char, your version would be illegal.

    Similarly, if either field1 or field2 happened to be const.




    Brian
     
    Default User, Apr 27, 2006
    #8
  9. gustavo

    Flash Gordon Guest

    edware wrote:

    <snip>

    > struct test_t {
    > char *a;
    > int b;
    > double c;
    > };
    >
    > int main(void)
    > {
    > struct test_t test = { 0 };
    > }
    >
    > Will this initialization set the whole struct to 0,
    > or just the first member, byte, or something like that?


    It will initialise the entire struct so appropriate 0 type values (null
    pointers, 0, 0.0 as appropriate). If you initialise any of it to any
    value then the rest gets initialised to an appropriate 0 value for the type.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc

    Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
     
    Flash Gordon, Apr 27, 2006
    #9
  10. gustavo

    CBFalconer Guest

    Flash Gordon wrote:
    > edware wrote:
    >
    > <snip>
    >
    >> struct test_t {
    >> char *a;
    >> int b;
    >> double c;
    >> };
    >>
    >> int main(void)
    >> {
    >> struct test_t test = { 0 };
    >> }
    >>
    >> Will this initialization set the whole struct to 0,
    >> or just the first member, byte, or something like that?

    >
    > It will initialise the entire struct so appropriate 0 type values
    > (null pointers, 0, 0.0 as appropriate). If you initialise any of
    > it to any value then the rest gets initialised to an appropriate
    > 0 value for the type.


    NOT to null pointers. Those you have to handle yourself.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, Apr 27, 2006
    #10
  11. CBFalconer <> writes:
    > Flash Gordon wrote:
    >> edware wrote:
    >>
    >> <snip>
    >>
    >>> struct test_t {
    >>> char *a;
    >>> int b;
    >>> double c;
    >>> };
    >>>
    >>> int main(void)
    >>> {
    >>> struct test_t test = { 0 };
    >>> }
    >>>
    >>> Will this initialization set the whole struct to 0,
    >>> or just the first member, byte, or something like that?

    >>
    >> It will initialise the entire struct so appropriate 0 type values
    >> (null pointers, 0, 0.0 as appropriate). If you initialise any of
    >> it to any value then the rest gets initialised to an appropriate
    >> 0 value for the type.

    >
    > NOT to null pointers. Those you have to handle yourself.


    YES to null pointers.

    C99 6.7.8p10:

    If an object that has automatic storage duration is not
    initialized explicitly, its value is indeterminate. If an object
    that has static storage duration is not initialized explicitly,
    then:

    -- if it has pointer type, it is initialized to a null pointer;

    -- if it has arithmetic type, it is initialized to (positive or
    unsigned) zero;

    -- if it is an aggregate, every member is initialized
    (recursively) according to these rules;

    -- if it is a union, the first named member is initialized
    (recursively) according to these rules.

    C99 6.7.8p21:

    If there are fewer initializers in a brace-enclosed list than
    there are elements or members of an aggregate, or fewer characters
    in a string literal used to initialize an array of known size than
    there are elements in the array, the remainder of the aggregate
    shall be initialized implicitly the same as objects that have
    static storage duration.

    --
    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, Apr 28, 2006
    #11
  12. gustavo

    CBFalconer Guest

    Keith Thompson wrote:
    > CBFalconer <> writes:
    >> Flash Gordon wrote:
    >>> edware wrote:
    >>> <snip>
    >>>
    >>>> struct test_t {
    >>>> char *a;
    >>>> int b;
    >>>> double c;
    >>>> };
    >>>>
    >>>> int main(void)
    >>>> {
    >>>> struct test_t test = { 0 };
    >>>> }
    >>>>
    >>>> Will this initialization set the whole struct to 0,
    >>>> or just the first member, byte, or something like that?
    >>>
    >>> It will initialise the entire struct so appropriate 0 type values
    >>> (null pointers, 0, 0.0 as appropriate). If you initialise any of
    >>> it to any value then the rest gets initialised to an appropriate
    >>> 0 value for the type.

    >>
    >> NOT to null pointers. Those you have to handle yourself.

    >
    > YES to null pointers.
    >
    > C99 6.7.8p10:
    >
    > If an object that has automatic storage duration is not
    > initialized explicitly, its value is indeterminate. If an object
    > that has static storage duration is not initialized explicitly,
    > then:
    >
    > -- if it has pointer type, it is initialized to a null pointer;
    >
    > -- if it has arithmetic type, it is initialized to (positive or
    > unsigned) zero;
    >
    > -- if it is an aggregate, every member is initialized
    > (recursively) according to these rules;
    >
    > -- if it is a union, the first named member is initialized
    > (recursively) according to these rules.
    >
    > C99 6.7.8p21:
    >
    > If there are fewer initializers in a brace-enclosed list than
    > there are elements or members of an aggregate, or fewer characters
    > in a string literal used to initialize an array of known size than
    > there are elements in the array, the remainder of the aggregate
    > shall be initialized implicitly the same as objects that have
    > static storage duration.


    Thanks for the correction. I was confusing it with the
    'all-bits-zero' case, and in fact I did know better, because I
    frequently use that characteristic to control auto-initialization.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, Apr 29, 2006
    #12
  13. CBFalconer <> writes:

    >> It will initialise the entire struct so appropriate 0 type values
    >> (null pointers, 0, 0.0 as appropriate). If you initialise any of
    >> it to any value then the rest gets initialised to an appropriate
    >> 0 value for the type.

    >
    > NOT to null pointers. Those you have to handle yourself.
    >


    Then my ISO setting on gnu c doesnt work : because it certainly does
    here. Come to think of it, it would be ludicrous if it didn't.
     
    Richard G. Riley, May 2, 2006
    #13
  14. Richard G. Riley wrote:
    > CBFalconer <> writes:
    >
    > >> It will initialise the entire struct so appropriate 0 type values
    > >> (null pointers, 0, 0.0 as appropriate). If you initialise any of
    > >> it to any value then the rest gets initialised to an appropriate
    > >> 0 value for the type.

    > >
    > > NOT to null pointers. Those you have to handle yourself.
    > >

    >
    > Then my ISO setting on gnu c doesnt work : because it certainly does
    > here. Come to think of it, it would be ludicrous if it didn't.


    Right, Chuck acknowleged this a couple of days ago.
    However, even if the pointers were not guaranteed to be initialized it
    wouldn't mean that a comforming implementation couldn't do so or that
    they might not wind up as NULL for some other reason.

    Robert Gamble
     
    Robert Gamble, May 2, 2006
    #14
  15. "Robert Gamble" <> writes:

    > Richard G. Riley wrote:
    >> CBFalconer <> writes:
    >>
    >> >> It will initialise the entire struct so appropriate 0 type values
    >> >> (null pointers, 0, 0.0 as appropriate). If you initialise any of
    >> >> it to any value then the rest gets initialised to an appropriate
    >> >> 0 value for the type.
    >> >
    >> > NOT to null pointers. Those you have to handle yourself.
    >> >

    >>
    >> Then my ISO setting on gnu c doesnt work : because it certainly does
    >> here. Come to think of it, it would be ludicrous if it didn't.

    >
    > Right, Chuck acknowleged this a couple of days ago.
    > However, even if the pointers were not guaranteed to be initialized it
    > wouldn't mean that a comforming implementation couldn't do so or that
    > they might not wind up as NULL for some other reason.
    >
    > Robert Gamble
    >


    So he (begrudgingly) did. I apologise for repeating this.
     
    Richard G. Riley, May 2, 2006
    #15
    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. Patricia  Van Hise

    structs with fields that are structs

    Patricia Van Hise, Apr 5, 2004, in forum: C Programming
    Replies:
    5
    Views:
    671
    Al Bowers
    Apr 5, 2004
  2. Chris Hauxwell

    const structs in other structs

    Chris Hauxwell, Apr 23, 2004, in forum: C Programming
    Replies:
    6
    Views:
    591
    Chris Hauxwell
    Apr 27, 2004
  3. Paminu
    Replies:
    5
    Views:
    662
    Eric Sosman
    Oct 11, 2005
  4. Daniel Rudy
    Replies:
    15
    Views:
    1,454
    Keith Thompson
    Apr 10, 2006
  5. lovecreatesbeauty
    Replies:
    1
    Views:
    1,159
    Ian Collins
    May 9, 2006
Loading...

Share This Page