This is ultimately a C question that arose when studying code in completion.h of the Linux kernel source, where I see a C technique I've never used in C before. Although have a vague sense what it's doing, I'd like to fine tune my understanding with a precise description, and I'm not quite sure how to search for the answer with Google without a potentially a long ordeal.
The relevant lines of code from the linux kernel's completion.h:
struct completion {
unsigned int done;
wait_queue_head_t wait;
};
#define COMPLETION_INITIALIZER_ONSTACK(work) \
(*({ init_completion(&work); &work; }))
#define DECLARE_COMPLETION_ONSTACK(work) \
struct completion work = COMPLETION_INITIALIZER_ONSTACK(work)
static inline void init_completion(struct completion *x)
{
x->done = 0;
init_waitqueue_head(&x->wait);
}
and in use:
int myFunc()
{
DECLARE_COMPLETION_ON_STACK(comp);
.
.
.
wait_for_completion(&comp);
}
Specifically, I want to understand the code
of COMPLETION_INITIALIZER_ON_STACK
.
I believe the braced body of two statements { init_completion(&work); &work; }
results in simply a value, &work
(a NOP statement), which from what I know about braced blocks in C, yeilds the value of the last assignment, in this case, the address of a struct.
But it is the enclosing of all of that in *( )
that gets interesting (and where I am bewildered).
- What is that 'fetch' doing exactly?
- Is it resulting in the function
init_completion()
being invoked (probably)? - And what is the result of a pointer to a struct as a fetched object?
- In what contexts can it be applied?
I'm not sure what is happening, how to conceive of it, and how it is it possible to assign that result to struct completion work
as is done in in DECLARE_COMPLETION_ON_STACK
.
Any education about this would be appreciated.