views:

1776

answers:

4

This is such a dumb question it's frustrating even asking it. Please, bear with me, I'm feeling particularly dumb over this one today....

I've got a library with a certain typedef struct. basically:

typedef struct {int x; int y;} coords;

What I really wanted to do was declare in my header a variable array of this:

coords MyCoords[];

(I recently switched it to just coords *MyCoords; and then ran a MyCoords = new coords[4];)

and then in my init I wanted to hardcode some values in it.

MyCoords[] = {{0, 0}, {2, 2} etc.

I must just be brainfarting today because it's not letting me do any manner of simply putting in even something simple like MyCoords[0] = {0, 0}

sorry about some of the syntax above. Thanks for any help. I don't even care about hard-coding all the values at once. I'm now fine with just geting MyCoords[0] = {0, 0} working. I could do MyCoords[0].x = 0; MyCoords[0].y = 0 but then I'd never figure out what I'm doing wrong. Thanks a lot anyone..

+8  A: 

You can only initialize an array at the same spot you declare it. The form that will work is:

coords MyCoords[] = {{0, 0}, {2, 2}};

If you need to declare MyCoords in a header so that many modules can access it, I think the following will work:

extern coords MyCoords[];
Mark Ransom
+4  A: 

Well, what you created is not a variable array. It's an array whose size is not known. That array has an incomplete type, and can thus not be defined in C++. What you can do is to make it just a declaration by putting extern before it.

extern coords MyCoords[];

Then, in the .cpp file that initializes it, you can then create (define) that array - beware you should do it at namespace scope, outside any function, of course:

coords MyCoords[] = {{1, 2}, {3, 4}, ... };

If what you want is an array whose size is not known at compile time yet, but rather at runtime, you should use a std::vector:

std::vector< coords > MyCoords;

Then later if you fill it, do

MyCoords.push_back( coords(1, 2) );
MyCoords.push_back( coords(3, 4) );
....

Or create a local array and then initialize the vector using a copy of the elements of that array:

coords c[] = ....;
MyCoords.insert(MyCoords.end(), c, c + sizeof c / sizeof *c);

Well, in C, it is slightly different than in C++. You can define an array whose dimension isn't known. What happens is that it's taken to be a "tentative" definition. If at the end of the file (more precisely, of its translation unit, which is that file, and all the files it includes - meaning everything the compiler translates together) there is not a subsequent definition of it that includes the size, then the size is taken to be 1. However, in C++ there are no tentative definitions, and a definition that does not include the size and does not contain an initializer that can tell the size is an invalid C++ program.

For the reason why your code goes grazy, you are doing

MyCoords[0] = {0, 0}

Which the compiler will read as:

-> Set LHS to RHS
-> -> LHS is a variable of type `coords`. Fine
-> -> RHS is... hmm, `{0, 0}`. What the heck is it??

You see, the compiler has no clue what the right hand side is supposed to mean. C99, for that reason (1999 version of C) introduced so-called compound literals. It allows you to write

MyCoords[0] = (coords){0, 0};

And it will actually do what you want it to do - creating a right hand side value of type coord and assigns it to the left hand side. But you should just, already from a compatibility reason (many C compilers are not reasonable C99 compliant - and neither C++ nor C89 supports compound literals), use one of the previous ways i showed you.

Johannes Schaub - litb
+2  A: 

I'm not sure whether this is also a problem in your actual code, but:

typedef struct coords {int x, int y};

is not a complete typedef declaration in C, as it does not give a name to the type, only to the struct (struct tags are not in the same namespace as type names in standard C). To make the typedef declaration correct, you have to specify a name for the whole type struct coords {int x, int y}, as if you were declaring a variable of that type, like so:

typedef struct coords {int x, int y} coords;
crosstalk
A: 

It should be:

typedef struct coords {int x, int y} coords;
coords MyCoords[] = {{0, 0}, {2, 2}, {3, 4}};
Roberto Bonvallet