String literal in compound literal

I have a question about string literals inside compound literals.

As the lifetime of the struct S compound literal is inside the block surrounding the func call, I wonder if it still alright to use the name pointer inside the global gs variable. I guess the string literal "foo" is not bound to the lifetime of the compound literal but rather resides in .rodata? Is that right? At least gs.name still prints foo.

#include <stddef.h>
#include <stdio.h>

struct S
{
    const char *name;
    int size;
};    

static struct S gs;

static void func(struct S *s)
{
    gs = *s;
}

int main(void)
{
    {
        func(&(struct S){.name="foo",.size=20});
    }

    printf("name: %s size: %d\n", gs.name, gs.size);
    return 0;
}

>Solution :

I guess the string literal "foo" is not bound to the lifetime of the compound literal but rather resides in .rodata?

Yes. That is correct. In

 func(&(struct S){.name="foo",.size=20});

where "foo" initializes a pointer, it’s almost as if you had written (if that could be written in C):

 func(&(struct S){.name=(static const char[]){'f','o','o','\0'},.size=20});

(C doesn’t technically allow static on compound literals, and C’s string literals are really de-facto const-char-arrays, but their formal type is char[] without the const (for weird historical reasons)).

But be careful with it. In C, you can use string literals to initialize arrays, and if .name were an member array, then storing "it" (its decayed pointer) to a global variable would be ill-advised.

Leave a Reply