Initializing static structs

  • Thread starter Christian Christmann
  • Start date
C

Christian Christmann

Hi,

I have problems to initialize a static struct. Here is the meaningful
part of the code:

int main()
{
int pA = -100;

struct globalMixed4 {
int a;
int *b;
};

static struct globalMixed4 globMix4 =
{ 200, &pA }; // my line 70


When try to compile, I get the gcc error message:
struct.c:70: error: initializer element is not constant

The non-constant initializer element is &pA.
How can I make it const?
And in general, why does the compiler expect a const initializer?

Thank you.

Chris
 
E

Eric Sosman

Christian Christmann wrote On 03/23/06 17:29,:
Hi,

I have problems to initialize a static struct. Here is the meaningful
part of the code:

int main()
{
int pA = -100;

struct globalMixed4 {
int a;
int *b;
};

static struct globalMixed4 globMix4 =
{ 200, &pA }; // my line 70


When try to compile, I get the gcc error message:
struct.c:70: error: initializer element is not constant

The non-constant initializer element is &pA.
How can I make it const?

static int pA = -100;
And in general, why does the compiler expect a const initializer?

Because static variables exist throughout the
entire life of the program, their initialization must
take place before the program starts executing (that
is, before main() is called). Thus, the initialization
can only use expressions that can be evaluated before
execution starts. The address of an `auto' variable
like your original `pA' is not known until the block
that contains it is entered at run-time, hence that
address can't be determined before run-time.
 
P

pete

Christian said:
Hi,

I have problems to initialize a static struct. Here is the meaningful
part of the code:

int main()
{
int pA = -100;

struct globalMixed4 {
int a;
int *b;
};

static struct globalMixed4 globMix4 =
{ 200, &pA }; // my line 70

When try to compile, I get the gcc error message:
struct.c:70: error: initializer element is not constant

The non-constant initializer element is &pA.
How can I make it const?
And in general, why does the compiler expect a const initializer?

Objects with static duration are initialised
prior to program start, so they must be initialised with
values that are known at compile time, in other words,
they must be initialised with constant expressions.

The addresses of automatic variables aren't known
at compile time, main might be recursive.

The addresses of static variables and external variables
(aka "globals") are constant expressions.
 
M

Michael Mair

Eric said:
Christian Christmann wrote On 03/23/06 17:29,:


static int pA = -100;

Nit: This is not exactly the same as int pA = -100; if it
comes to using the value of pA in other initialisers.

In C89, we'd need
static int pA = -100;
.... /* declaration list */
pA = -100;
/* statement list */
pA = -100;
/* return if necessary */
and in C99,
static int pA;
pA = -100;
....

Cheers
Michael
 
E

Eric Sosman

Michael Mair wrote On 03/23/06 17:57,:
Nit: This is not exactly the same as int pA = -100; if it
comes to using the value of pA in other initialisers.

Right: `static' is not `auto'. I was addressing
the question of how to make `&pA' constant, not the
value stored in `pA' itself. Naturally, the change
has semantic effects beyond the mere address-constness.
 
B

Barry Schwarz

Hi,

I have problems to initialize a static struct. Here is the meaningful
part of the code:

int main()
{
int pA = -100;

struct globalMixed4 {
int a;
int *b;
};

static struct globalMixed4 globMix4 =
{ 200, &pA }; // my line 70


When try to compile, I get the gcc error message:
struct.c:70: error: initializer element is not constant

The non-constant initializer element is &pA.
How can I make it const?
And in general, why does the compiler expect a const initializer?
It requires it only for static variables. And even though the address
of pA will not change during execution of your program, it is not a
constant, just like
const int b =10;
does not make b a constant and
char x;
will produce a similar diagnostic on a non-C99 system.

If you make pA static, the problem should go away. For some reason,
the address of a static variable is a constant.


Remove del for email
 
S

shdxiahui

This is my first join in this area , I 'm a chinese , Would you
mind we are created a good friendship.
 
S

S.Tobias

Michael Mair said:
Nit: This is not exactly the same as int pA = -100; if it
comes to using the value of pA in other initialisers.
Could you, please, explain what exactly the problem is?
In C89, we'd need
static int pA = -100;
Assuming a block scope, above initialization would be
illegal, according to ansi_c draft.
.... /* declaration list */
pA = -100;
/* statement list */
pA = -100;
/* return if necessary */
and in C99,
static int pA;
pA = -100;
....

I can't see what the difference is between C89 and C99.
 
M

Michael Mair

S.Tobias said:
Could you, please, explain what exactly the problem is?

Of course. Consider
#include <stdio.h>
int ctr = 5;

int main (void)
{
int pA = -100;
int pB = pA * 2;

static struct { int a; int *b; } globMix4 = { 200, &pA };

--pA; --ctr; /* o */
printf("%d\n", pA);

if (ctr != 0)
(void) main();

return 0;
}
This will not compile.
If we assume that globMix4 could be initialised that way, then
we have pB == -200 at initialisation and pA == -101 at the last
time "o" is reached. For
#include <stdio.h>
int ctr = 5;

int main (void)
{
static int pA = -100;
int pB = pA * 2;

static struct { int a; int *b; } globMix4 = { 200, &pA };

--pA; --ctr; /* o */
printf("%d\n", pA);

if (ctr != 0)
(void) main();

return 0;
}
we have pB == -200, -202, ..., -208 and pA = -105 at the last time "o"
is reached.
Assuming a block scope, above initialization would be
illegal, according to ansi_c draft.

How so?

#include <stdio.h>
int ctr = 5;

int main (void)
{
static int pA = -100;
int pB = pA * 2;

static struct { int a; int *b; } globMix4 = { 200, &pA };

--pA; --ctr; /* o */
printf("%d\n", pA);

pA = -100; /* reset to effect of auto for next main() call */
if (ctr != 0)
(void) main();

return 0;
}

If you have a function not called recursively with an internal
state then resetting the value to the initialiser before returning
would have the desired effect.
I can't see what the difference is between C89 and C99.

In C99, you can make sure that pA really behaves as if initialised
to "-100" every time:

#include <stdio.h>
int ctr = 5;

int main (void)
{
static int pA = -100;
pA = -100;
int pB = pA * 2;

static struct { int a; int *b; } globMix4 = { 200, &pA };

--pA; --ctr; /* o */
printf("%d\n", pA);

if (ctr != 0)
(void) main();

return 0;
}

The C89 version of course works the same under C99 but has
the disadvantage that it may be necessary to reset pA in
more than one place -- or that it is not at all possible to
reset pA always correctly without introducing another variable.


Cheers
Michael
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,503
Latest member
supremedee

Latest Threads

Top