Defines the type x
and an array X
of that type.
x.h:
typedef struct _x {int p, q, r;} x;
extern x X[];
Separate file to keep the huge honking array X
.
x.c:
#include "x.h"
x X[] = {/* lotsa stuff */};
Now I want to use X
:
main.c:
#include "x.h"
int main()
{
int i;
for (i = 0; i < sizeof(X)/sizeof(x); i++) /* error here */
invert(X[i]);
return 0;
}
main.c
won't compile; the error is:
error: invalid application of ‘sizeof’ to incomplete type ‘struct x[]’
How do I get the size of X
without hardcoding it?
In x.h
add:
extern size_t x_count;
In x.c
add:
size_t x_count = sizeof(X)/sizeof(x);
Then use the variable x_count
in your loop.
The division has to be done in the compilation unit that contains the array initializer, so it knows the size of the whole array.
If it is possible to place a termination indicator at the end of the array, such as:
x X[] = {/* lotsa stuff */, NULL};
It might be that the number of elements in the array would be irrelevant:
#include "x.h"
int main()
{
x *ptr = X;
while(ptr)
invert(ptr++);
return 0;
}
If the number of elements in the array is needed, the above method can be also be used to count the elements.
Here a solution using compound literals:
in .h
typedef struct _x {int p, q, r} x;
#define LOTSA_STUFF {1, 2, 3}, {4, 5, 7}
#define LOTSA_STUFF_SIZE sizeof ((x[]) {LOTSA_STUFF})
extern x X[LOTSA_STUFF_SIZE];
and in .c
x X[LOTSA_STUFF_SIZE] = {LOTSA_STUFF};
For the definition in .c
, you can even do better and use a static assert (definition of the STATIC_ASSERT
is let as an exercise for the reader ;):
x X[] = {LOTSA_STUFF};
STATIC_ASSERT(sizeof X != LOTSA_STUFF_SIZE, "oops, sizes are not equal");
If you simply include x.h, the compiler has no idea what the real size of X is. Just by looking at x.h, there is no way to guess.
You have to declare X with a size:
extern x X[15];
You can't do that. But you can provide a way to get the size.
In addition to
extern x X[];
Add
extern size_t xArraySize;
or, preferably,
extern size_t xArraySize(void);
in x.h
Define it in x.c
.
Change your loop to:
for (i = 0; i < xArraySize(); i++)
invert(X[i]);