Use for anonymous structures
One place where an (array of an) anonymous structure can be useful is in code where the data is not needed outside the one function.
const char *info_lookup(int value)
{
static const struct { int number; char *name; } list[] =
{
{ 1, "twenty-seven" },
{ 13, "unfortunately" },
{ 27, "won" },
...
};
enum { NUM_LIST_ITEMS = sizeof(list) / sizeof(list[0]) };
for (i = 0; i < NUM_LIST_ITEMS; i++)
{
if (value <= list[i].number)
return(list[i].name);
}
return(0);
}
I also sometimes use it for running tests where the structure captures the test information:
static const struct
{
const char *ver1;
const char *ver2;
int result;
} test[] =
{
{ "7.0.4.27", "7.0.4.17", +1 },
{ "7.0.4.23", "7.0.4.17", +1 },
{ "7.0.4.23", "7.0.4.27", -1 },
{ "7.0.4.23", "7.0.5.07", -1 },
...20+ tests omitted...
};
enum { NUM_TESTS = DIM(test) };
static const char *result(int i)
{
if (i < 0)
return("<");
else if (i > 0)
return(">");
else
return("=");
}
int main(void)
{
size_t j;
int fail = 0;
for (j = 0; j < NUM_TESTS; j++)
{
int r1 = version_compare(test[j].ver1, test[j].ver2);
int r2 = version_compare(test[j].ver2, test[j].ver1);
const char *pass_fail = "PASS";
char extra[32] = "";
if (r1 != test[j].result)
{
pass_fail = "FAIL";
fail++;
snprintf(extra, sizeof(extra), " Expected %s", result(test[j].result));
}
assert(r1 == -r2);
printf("%s: %-10s %s %s%s\n",
pass_fail, test[j].ver1, result(r1), test[j].ver2, extra);
}
if (fail == 0)
{
printf("== PASS == %d tests passed\n", NUM_TESTS);
return(0);
}
else
{
printf("!! FAIL !! %d out of %d tests failed\n", fail, NUM_TESTS);
return(1);
}
}
It is only appropriate when nothing outside the file needs to know about the structure, and when there's only one variable of the type (or you can declare all the variables of the type in a single declaration, but I usually have just one declarator per declaration, so that amounts to one variable of the type).
If you need to refer to the type more than once, then it needs a name — either the structure tag or the typedef name or both.