I only recently learned that I can actually use references to compound literal arrays in C, which I find useful, but I don't quite understand how it works.
For instance, say that I use the feature to avoid having to declare a variable for a call some socket interface function where I don't care about the return name length, like this:
int sockfamily(int fd)
{
struct sockaddr_storage ss;
getpeername(fd, (struct sockaddr *)&ss, (socklen_t [1]){sizeof(ss)});
return(ss.ss_family);
}
Clearly, sizeof(ss)
needs to actually be stored on the stack in order for a pointer to it to be passed to getpeername
, and space on the stack must therefore be allocated and reserved for that purpose, but what is the lifetime of this allocation? How long can I trust it to remain allocated?
Looking at the assembly output of GCC, I observe that if I put the call to getpeername
in a loop, the allocation does not survive for multiple iterations of the loop, but what other conditions, then, might cause it to cease to exist?
A compound literal defined within a function has automatic lifetime associated with the block that contains it (i.e. the same lifetime as a variable declared on the same level). This is specified in the standard, paragraph 6.5.2.5p5.
int f() {
for (int i = 0; i < 10; ++i) {
int *j = (int []){i}; // storage duration of loop body
}
}
This essentially means that a compound literal is equivalent to a variable declared and initialized in the same scope:
int f() {
for (int i = 0; i < 10; ++i) {
int __unnamed[] = {i};
int *j = __unnamed;
}
}
Take care if passing compound literals anywhere their pointers could persist past their lifetime:
int f() {
int *p;
if (1) {
p = (int []){0, 1, 2};
assert(p[0] == 0);
}
// *p is undefined
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With