Is it allowed to take the address of an object on the right hand-side of its definition, as happens in foo()
below:
typedef struct { char x[100]
To answer the question in the title, with your code sample in mind, yes it may. The C standard says as much in §6.2.4:
The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime.
For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way.
So yes, you may take the address of a variable from the point of declaration, because the object has the address at this point and it's in scope. A condensed example of this is the following:
void *p = &p;
It serves very little purpose, but is perfectly valid.
As for your second question, what can you do with it. I can mostly say I wouldn't use that address to access the object until initialization is complete, because the order of evaluation for expressions in initializers is left unsepcified (§6.7.9). You can easily find your foot shot off.
One place where this does come through, is when defining all sorts of tabular data structures that need to be self referential. For instance:
typedef struct tab_row {
// Useful data
struct tab_row *p_next;
} row;
row table[3] = {
[1] = { /*Data 1*/, &table[0] },
[2] = { /*Data 2*/, &table[1] },
[0] = { /*Data 0*/, &table[2] },
};