Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

532 views
Skip to first unread message

bingfeng

unread,
Jun 1, 2005, 2:17:01 AM6/1/05
to
I have some codes generated by perl, in which initialize some huge
struct,such as

PARA TOS_network_spantree_set_0_para_0 = { "vlan", emNUM, NULL, "",
"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",
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


Jack Klein

unread,
Jun 1, 2005, 2:38:08 AM6/1/05
to
On Wed, 1 Jun 2005 14:17:01 +0800, "bingfeng"
<zhao_b...@topsec.com.cn> 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

Richard Bos

unread,
Jun 1, 2005, 3:11:24 AM6/1/05
to
Jack Klein <jack...@spamcop.net> wrote:

> On Wed, 1 Jun 2005 14:17:01 +0800, "bingfeng"
> <zhao_b...@topsec.com.cn> wrote in comp.lang.c:
>

> > 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?
>

> 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.

> 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.

_And_ the exact text of the warning itself. It could warn about
"incompatible types" or about "uninitialised objects" or about "your
indentation style is ugly", and the solution would be different in each
case.

Richard

Chris Torek

unread,
Jun 1, 2005, 1:55:17 PM6/1/05
to
>> On Wed, 1 Jun 2005 14:17:01 +0800, "bingfeng"
>> <zhao_b...@topsec.com.cn> wrote in comp.lang.c:
>>>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?

>Jack Klein <jack...@spamcop.net> wrote:
>>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.

Indeed -- although I suspect the problem causing the crash is something
else entirely.

>>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.

In article <429d5f4c...@news.xs4all.nl>,


Richard Bos <r...@hoekstra-uitgeverij.nl> wrote:
>_And_ the exact text of the warning itself. It could warn about
>"incompatible types" or about "uninitialised objects" or about "your
>indentation style is ugly", and the solution would be different in each
>case.

As it happens, the exact text of the warning is in the "subject"
header line. But this is not always visible to everyone when
reading the message body, so it should be repeated in (or moved
to) the message body:

"warning: initializer element is not computable at load time"

This particular warning is one that GCC emits when you use GCC's
C89-extension that allows initializing aggregates with non-constant
values. For instance:

% cat t.c
void f(int x, int y) {
int a[2] = { x, y };
...
}

This code is allowed in C99, but not in C89. GCC allows it even
without -std=c99, but will issue a diagnostic when requested:

% cc -O2 -c -W -Wall t.c
% cc -ansi -pedantic -O2 -c t.c
t.c: In function `f':
t.c:3: warning: initializer element is not computable at load time
t.c:3: warning: initializer element is not computable at load time
% cc -std=c99 -pedantic -O2 -c t.c
%

(note that "-ansi" means the same as "-std=c89", and "-pedantic"
is the option that tells GCC to emit the required diagnostic).
--
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.

bingfeng

unread,
Jun 1, 2005, 9:55:01 PM6/1/05
to
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" <jack...@spamcop.net> ????
news:cglq91tld0arm5vum...@4ax.com...

bingfeng

unread,
Jun 2, 2005, 5:45:39 AM6/2/05
to
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" <zhao_b...@topsec.com.cn> 写入邮件
news:d7lpjg$2r5q$1...@mail.cn99.com...

Keith Thompson

unread,
Jun 2, 2005, 7:04:50 PM6/2/05
to
"bingfeng" <zhao_b...@topsec.com.cn> 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) ks...@mib.org <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

unread,
Jun 3, 2005, 2:06:39 AM6/3/05
to

"Keith Thompson" <ks...@mib.org> ???? news:ln7jhce...@nuthaus.mib.org...

> "bingfeng" <zhao_b...@topsec.com.cn> 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 :)

Chris Torek

unread,
Jun 6, 2005, 12:49:07 AM6/6/05
to
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" <ks...@mib.org> ???? news:ln7jhce...@nuthaus.mib.org...


>> 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$1...@mail.cn99.com>,


bingfeng <zhao_b...@topsec.com.cn> 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 [b] 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. :-) )

0 new messages