Re: what's meaning of "warning: initializer element is not computable at load time"

Discussion in 'C Programming' started by bingfeng, Jun 2, 2005.

  1. bingfeng

    bingfeng Guest

    My fellows said it's a common case to initialize struct with local variables
    in function scope. Is he right? I want to know why gcc(C99/C++) reluctant
    give some warning for this case. I think its a fatal potential bug!

    Welcome comments



    "bingfeng" <> дÈëÓʼþ
    news:d7lpjg$2r5q$99.com...
    > thanks to all warmhearted persons at first!
    >
    > I know the exact answer of that question: I initialized a huge struct in a
    > function then return the address of struct to caller! Auto variables are

    not
    > stored in static memory, so loader cannot load it properly. Of course,

    it's
    > a fundamental to use static variables in such case, but the parts are in
    > global at first. I didn't want to introduce too many global names to

    global
    > namespace, and it seems initialize such struct is impossible, so I move it
    > into a function scope and emit add static keyword(you know, all the code

    was
    > generated automatic by some other tool). The difference of result C89, C99
    > and C++
    > generated misled I compare the different features they supported, sigh!
    >
    > As to the coredump, someone told me maybe too many local variables occupy

    a
    > lot of stack, and my test routine use recursive calls, all of that in

    eacess
    > of size of stack, so app crashed. I think him is right.
    >
    > If gcc mention "local variable" or "auto variable", I would notice such
    > basic and important bug, but I spend four hours before I ask others view

    my
    > code!
    >
    >
    > "Jack Klein" <> ????
    > news:...
    > > On Wed, 1 Jun 2005 14:17:01 +0800, "bingfeng"
    > > <> wrote in comp.lang.c:
    > >
    > > > I have some codes generated by perl, in which initialize some huge
    > > > struct,such as

    > >
    > > PERL is off-topic here, and your code snippet is littered with types
    > > not defined by C, so it is hard to tell.
    > >
    > > > PARA TOS_network_spantree_set_0_para_0 = { "vlan", emNUM, NULL,

    "",
    > >
    > > What is the definition of the type 'PARA'? It appears to be 'pointer
    > > to pointer to char' or 'pointer to pointer to const char'.
    > >
    > > > "configuration on a designated vlan", PRO_REQUIRED };
    > > > const char* TOS_network_spantree_set_0_para_1_emvalue[] = {

    > "disable",
    > > > "enable", NULL };
    > > > PARA TOS_network_spantree_set_0_para_1 = { "", emENUM,
    > > > TOS_network_spantree_set_0_para_1_emvalue, "", "enable or disable

    STP",
    > >
    > > If I am right about the definition of 'PARA', the initialization of is
    > > wrong. "" and "enable or disable STP" are string literals, but
    > > 'TOS_network_spantree_set_0_para_1_emvalue' decays into a pointer to
    > > pointer to char, a different type.
    > >
    > > > PRO_REQUIRED };
    > > > PPARA TOS_network_spantree_set_0_para[] = {
    > > > &TOS_network_spantree_set_0_para_0,
    > > > &TOS_network_spantree_set_0_para_1,
    > > > NULL
    > > > }
    > > > ......
    > > >
    > > > gcc(C89 setting) report warnings about that, but C99 not. I ignore

    those
    > > > warnings and try to dump the struct, the program crashed after some

    > output.
    > > > what wrong and how I can fix it?
    > > >
    > > > thanks a lot

    > >
    > > I would say you have two options, one is to post the definitions of
    > > all the UPPER CASE types and values used in the code snippet. The
    > > other is to talk to the person who wrote the PERL code that generates
    > > this, as it seems to be incorrect.
    > >
    > > By the way, it is a very good idea indicate the exact line of your
    > > code snippet that the compiler indicated was the cause of the error.
    > >
    > > --
    > > Jack Klein
    > > Home: http://JK-Technology.Com
    > > FAQs for
    > > comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    > > comp.lang.c++ http://www.parashift.com/c -faq-lite/
    > > alt.comp.lang.learn.c-c++
    > > http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

    >
    >
     
    bingfeng, Jun 2, 2005
    #1
    1. Advertising

  2. Re: what's meaning of "warning: initializer element is notcomputable at load time"

    "bingfeng" <> writes:
    > My fellows said it's a common case to initialize struct with local variables
    > in function scope. Is he right? I want to know why gcc(C99/C++) reluctant
    > give some warning for this case. I think its a fatal potential bug!
    >
    > Welcome comments


    Please don't top-post. Your response should be below, or interspersed
    with, any quoted text, so the entire article can be read coherently
    from top to bottom. Snip anything that's not relevant to your
    followup. See most of the articles in this newsgroup for examples of
    how to do this properly.

    I don't understand what you're asking. There's nothing wrong in
    general with using local variables in the initialization of a struct.
    Returning the address of a local variable from a function is
    dangerous.

    If you can given an example of what you're talking about, we can
    comment further. (Note that C++ is off-topic here; if your example
    isn't pure C it's likely to be ignored.)

    --
    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, Jun 3, 2005
    #2
    1. Advertising

  3. bingfeng

    bingfeng Guest

    "Keith Thompson" <> ???? news:...
    > "bingfeng" <> writes:
    > > My fellows said it's a common case to initialize struct with local

    variables
    > > in function scope. Is he right? I want to know why gcc(C99/C++)

    reluctant
    > > give some warning for this case. I think its a fatal potential bug!
    > >
    > > Welcome comments

    >
    > Please don't top-post. Your response should be below, or interspersed
    > with, any quoted text, so the entire article can be read coherently
    > from top to bottom. Snip anything that's not relevant to your
    > followup. See most of the articles in this newsgroup for examples of
    > how to do this properly.
    >

    Sorry for that

    > I don't understand what you're asking. There's nothing wrong in
    > general with using local variables in the initialization of a struct.
    > Returning the address of a local variable from a function is
    > dangerous.
    >

    Consider following code:
    #include <stdio.h>
    struct node
    {
    const char* name_;
    int type_;
    const char** emvalue_;
    const char* mc_;
    const char* me_;
    int property_;
    };

    struct branch
    {
    struct node** pn_;
    const char* desc_;
    };

    void foo(struct branch* pb)
    {
    struct node n1 = { "vlan", 1, NULL, "mc", "me", 0 };
    const char* em[] = { "disable", "enable", NULL };
    struct node n2 = { "", 1, em, "some ...", "other...", 1 };
    struct node* pn[] = { &n1, &n2, NULL };
    struct branch b = { pn, "sample" };
    *pb = b;
    }


    int main(void)
    {
    struct branch b;
    foo(&b)
    /* use b now...*/

    return 0;
    }

    Is it security to use b then? In my code, there are many such initialzied
    structs and when I dump all its content recursively, it crashed after some
    output.
    gcc(gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) can compile it
    without any warning.

    > If you can given an example of what you're talking about, we can
    > comment further. (Note that C++ is off-topic here; if your example
    > isn't pure C it's likely to be ignored.)
    >

    I think my code is pure C code :)

    > --
    > 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.
     
    bingfeng, Jun 3, 2005
    #3
  4. bingfeng

    Chris Torek Guest

    In case the "subject:" line is not visible, let me repeat it here:

    what's meaning of "warning: initializer element is not
    computable at load time"

    >"Keith Thompson" <> ???? news:...
    >> I don't understand what you're asking. There's nothing wrong in
    >> general with using local variables in the initialization of a struct.
    >> Returning the address of a local variable from a function is
    >> dangerous.


    In article <d7osnl$h3m$99.com>,
    bingfeng <> wrote:
    >Consider following code:
    >#include <stdio.h>
    >struct node
    >{
    > const char* name_;
    > int type_;
    > const char** emvalue_;
    > const char* mc_;
    > const char* me_;
    > int property_;
    >};
    >
    >struct branch
    >{
    > struct node** pn_;
    > const char* desc_;
    >};
    >
    >void foo(struct branch* pb)
    >{
    > struct node n1 = { "vlan", 1, NULL, "mc", "me", 0 };
    > const char* em[] = { "disable", "enable", NULL };


    So far, all of this code is valid C89.

    > struct node n2 = { "", 1, em, "some ...", "other...", 1 };
    > struct node* pn[] = { &n1, &n2, NULL };
    > struct branch b = { pn, "sample" };


    These initializations are valid C99 but not valid C89. In particular,
    em (aka &em[0]), &n1, &n2, and pn (aka &pn[0]) are not constants,
    and not computable at load time. All of the variables -- n1, em,
    n2, pn, and b -- have automatic storage duration and are thus
    created when foo() is entered, and destroyed when foo() returns.
    (This is what makes &n1, &em[0], &n2, and &pn[0] "non-constant":
    the addresses of the variables do not even exist until foo() is
    called. If foo() is entered recursively, new and different variables,
    with the same name but different addresses, spring into being.)

    > *pb = b;


    As Keith Thompson noted, "returning the address of a local variable
    from a function is dangerous". While you are not using a "return"
    statement, you are in fact returning the address of a local variable.
    The assignment "*pb = b" copies the entire structure named "b"
    to *pb. Part of this is OK, and part is "dangerous" (not OK).

    The field b.desc_ points to the 's' in "sample", a string produced
    due to the string literal. This string has static duration, i.e.,
    persists for the entire lifetime of the program. This is OK: the
    address of the 's' in "sample" remains valid while the program runs
    (and once the program exits, well, who cares?).

    The field b.pn_, on the other hand, points to the automatic-duration
    local variable pn[0]. This variable ceases to exist as soon as
    foo() returns. Copying the pointer value from b.pn_ to (*pb).pn_
    sets (*pb).pn_ to a value that becomes invalid as soon as foo()
    returns.

    >}


    Now foo() returns, and pn[0], pn[1], n2, em[0], em[1], em[2], and
    n1 all cease to exist -- at least in principle. But (*pb).pn_
    still points to the place pn[0] used to live; and the values that
    used to be in pn[0] and pn[1] may, and probably will, still be
    there -- or seem to be there -- for a while. This is one of the
    ways in which "undefined behavior" manifests: the program *seems*
    to work, until some time later, when something important is going
    on. :)

    >int main(void)
    >{
    > struct branch b;
    > foo(&b);


    Here, the pointer *pb in foo() points to b, so it is b.pn_ that
    now holds an invalid value. (As noted earlier, b.desc_ is valid.)

    > /* use b now...*/
    > return 0;
    >}
    >... when I dump recursively, it crashed after some output.


    Using b.pn_ will result in undefined behavior, possibly including
    "seems to work" and/or "core dump"/crash.

    To fix the problem, make sure that your pointers point to valid
    values. Automatic variables' storage duration (lifetime) is limited
    to "while the enclosing block executes". Static or malloc()ed
    storage persists longer: static-duration variables' lifetime is
    "while the program runs", and malloc() ("allocated" duration) memory
    lasts until explicitly free()d, or (as with static duration) when
    the program terminates. (Whether un-free()d memory is released is
    not addressed by the Standard -- which also does not address whether
    static-duration variables cease to exist when the program finishes.
    As far as the Standard is concerned, neither question is interesting,
    because C programs only exist until they finish, after which the
    universe vanishes entirely. :) )
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Jun 6, 2005
    #4
    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. Sander Odekerken

    Meaning of output value?

    Sander Odekerken, May 18, 2004, in forum: VHDL
    Replies:
    2
    Views:
    2,562
    John_H
    May 18, 2004
  2. Parthav
    Replies:
    4
    Views:
    2,048
    Mike Treseler
    Jan 13, 2006
  3. Frank

    Meaning of <%#

    Frank, Dec 30, 2003, in forum: ASP .Net
    Replies:
    4
    Views:
    596
  4. bingfeng
    Replies:
    4
    Views:
    2,787
    bingfeng
    Jun 2, 2005
  5. Replies:
    4
    Views:
    821
Loading...

Share This Page