LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

C Structure Initialization: compiler problem?

LabWindows/CVI 6.0 compiler gives compile error, but gcc 3.3.1 compiler compiles without error.

I have a C program, with a structure, which has a member that's a pointer to another structure, as follows:

//start of code
struct x {
int year;
char fname[30];
struct data *pdata; //pointer to the structure 'data', defined below.
};

struct data {
float freq;
int pwrlevel;
char freqname[20];
};

main()
{
struct data first = {400.25, 25, "GM1"};
struct x point1 = {2003, "TestFile1", &first};
//rest of code;

}

The question is, how do I initialize the point1 structure in main()?

The method I used above doesn't work. The compiler chokes on &first, generati
ng a compile error which says "initializer must be constant". But doesn't &first evaluate to a constant? Or is this method of initialization not 'allowed'? Can anybody shed some light on this?

Thanks.
0 Kudos
Message 1 of 7
(4,876 Views)
The compiler is expecting a constant because you're declaring and initializing point1 in the same statement. You could either declare the structure in one statement and explicitly initialize each field in subsequent statements (see point2 below), or you could declare and initialize it in one statement, initializing pdata to an arbitrary pointer value, and then update pdata in the next statement (see point1 below).
main()
{
char bitBucket[80];

struct data first = {400.25, 25, "GM1"};
struct data next1 = {450.00, 10, "GM2"};

// declare and initialize point1 in the same statement.
// pdata (initialized to 0) must be updated before use!
struct x point1 = {2003, "TestFile1", 0};
struct x point2;

// update pdata to point t
o first
point1.pdata = &first;

// initialize each field of point2
point2.year = 2003;
strcpy(point2.fname, "TestFile2");
point2.pdata = &next1;

printf("File: %s\nYear: %d\nFrequency: %f\nPower %d\n",
point1.fname, point1.year,
point1.pdata->freq, point1.pdata->pwrlevel);
printf("File: %s\nYear: %d\nFrequency: %f\nPower %d\n",
point2.fname, point2.year,
point2.pdata->freq, point2.pdata->pwrlevel);

printf("Press Enter to continue: ");
gets(bitBucket);
}
Message 2 of 7
(4,876 Views)
You also asked "doesn't &first evaluate to a constant?".
No. &first is the address of the variable named first. The compiler does not see it as a constant because that address is set at runtime, not at compile time. The compiler doesn't know where Windows is going to run that code.
0 Kudos
Message 3 of 7
(4,876 Views)
Thanks. That explanation helps a lot.

But, for point1, why isn't "point1.pdata=&first" the same thing as using the initializer as originally proposed (initializing during declaration of point1)?

I mean, I'm still not quite clear why declaring and initializing at the same time is different from declaring, then initializing in another statement.

Is it that "point1.pdata=&first" is evaluated at run time, when the value of &first is known, whereas the declaration must be done at compile time, at at time where the value of &first is unknown?

-koons9576
0 Kudos
Message 4 of 7
(4,876 Views)
The compiler looks at declarations differently than separate initializations because of compile-time/run-time differences. I checked several ANSI C references and they say when initializing structures in a declaration statement, anything within the curly braces must be constant. So it's not just a CVI thing.
0 Kudos
Message 5 of 7
(4,876 Views)
You declared "first" as an automatic variable (by leaving out the "static"
keyword) which is created on the stack at runtime. That's why the CVI compiler
correctly complains that its not constant. If you declare "first" as a static
variable, CVI will compile your code without complaint, e.g.

static struct data first = {400.25, 25, "GM1"};

If the Gnu compiler doesn't complain about the way you origianally had it
declared then it must be treating "first" as a static variable even though its
not, since it is declared within the scope of a function. Thats not strictly
correct compiler behaviour for K&R C, but maybe the latest ANSI C (1999)
standard allows it? Per K&R, only variables declared at the module level are
static by default.
0 Kudos
Message 6 of 7
(4,876 Views)
That pretty much clears it up then.

I tried to compile as orginally written using a Borland compiler, and had the same problem.

Then I tried it in CVI with 'first' delcared as a static and it worked, as you said it would.

Maybe the Gnu compiler automatically treats the block level declaration of statics defined at the module level as statics. Or there's an option set to make it act that way, or as you mentioned, maybe the latest ANSI C standard allows it. Although there's no way it could initialize it with the actual value of &first until run time, since that value doesn't exist until then.

Thanks ALS and Nick J for your replies...
0 Kudos
Message 7 of 7
(4,876 Views)