Then take away the names so that you are effectively passing p as a parameter... Then returning p.
As in, an anonymous temporary being given to the function, and the function returns its address back.
It's assuming that this temporary parameter buffer will exist after it is used and the function has returned. I'm not sure what the standard says for that but it is crazy sketchy. [Edit: Googling around, it seems like maybe this is illegal in C99 but possibly legal in C11? Or that C11 changed the rules for this. Does not seem like a great thing to rely upon.]
There is no issue here (except the one highlighted by joejev).
Many standard library functions return a pointer which they got as a parameter (or another pointer offset from it, as is the case here). The compound literal is no more "temporary" than a variable that was introduced right before the function call. Lifetimes of compound literals are specified in section 6.5.2.5 of both C99 and C11.
func((int[256]){ 0 });
// is mostly equivalent to
int __a__[256] = { 0 };
func(__a__);
> Many standard library functions return a pointer which they got as a parameter
Obviously. But this does not extend the lifetime of the buffer they are passed. Namely you can't use this as a technique to extend the life of automatic storage falling out of scope.
> Lifetimes of compound literals are specified in section 6.5.2.5 of both C99 and C11.
This is what I was missing. So it is valid by the standard. Which is good if you have looked it up. It remains not obvious when reading source without a copy of the standard on hand, or prior knowledge of that section. Passing an expression of that sort and keeping a pointer to it visually looks like the intent is to retain a pointer of more limited scope. Intuitively it would make just as much sense if the lifetime were shorter. If you are seeking clarity of intent this is not a great thing to rely upon.
var is a typedef for void* and no & appears in the function.