Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Taking address of temporary (compound literal) parameter in C

I can't imagine this isn't already duplicate, but I can't easily find the answer since the more complex scenarios specifically to C++ seem to dominate the discussion0.

Is it legal to take take the address of a temporary constructed in the parameter list of a function call in C99?

For example, something like init_list or init_desig_init as follows:

typedef struct {
  int x;
  int y;
} point_t;

int manhattan(point_t *p) {
  return p->x + p->y;
}

int init_list() {
  return manhattan(&(point_t){1, 2});
}

int init_desig_init() {
  return manhattan(&(point_t){.x = 1});
}

The big three1seem to compile it OK, but I couldn't actually find a reference explaining that the lifetime of the temporary will be extended at least through the function call.


0 As it turns out, based on the answer by M.M below, part of my searching issues was because I was looking for information on temporaries, while the correct C term for this particular initialization construct is compound literal.

1 I should call it "the big cross-platform three" really, in deference to MSVC, but actually I really just mean "the C compilers godbolt supports".

like image 879
BeeOnRope Avatar asked Jan 29 '17 23:01

BeeOnRope


1 Answers

(point_t){1, 2} is not a "temporary". It is a compound literal. (The same sequence of tokens in C++ has a different meaning, these two languages should not be confused with each other).

A compound literal is an lvalue, so it is legal to use the unary & operator on it. The storage duration is covered by C11 6.5.2.5/5:

If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

So this code is correct, and the compound literal keeps existing until the end of the function it was declared in.

like image 70
M.M Avatar answered Nov 15 '22 01:11

M.M