Taking address of temporary (compound literal) parameter in C
Asked Answered
I

1

19

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 three1 seem 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".

Isocracy answered 29/1, 2017 at 23:38 Comment(2)
The answer you got is good, but there's a little gotcha that is worth keeping in mind when you start using compound literals more extensively: #34881138Monson
@Monson - very good point. As it if wasn't already enough trying to remember the different lifetime rules for compound literals in C versus temporaries in C++...Isocracy
M
17

(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.

Macaco answered 30/1, 2017 at 1:6 Comment(1)
Thank you. My use of "temporary" also partly explains why I had such a tough time searching for the details on this. For additional reference, here's the gcc doc on compound literals.Isocracy

© 2022 - 2024 — McMap. All rights reserved.