Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lifetime of referenced compound array literals

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?

like image 211
Dolda2000 Avatar asked Dec 21 '22 09:12

Dolda2000


1 Answers

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
}
like image 115
ecatmur Avatar answered Dec 24 '22 02:12

ecatmur