复合字面值中的字符串字面值

3

我有一个关于复合字面量中字符串文字的问题。

由于结构体S复合字面量的生命周期在包围函数调用的块内,因此我想知道是否仍然可以在全局变量gs中使用名称指针。我猜字符串文字"foo"不是绑定到复合字面量的生命周期中,而是驻留在.rodata中?是这样吗?至少gs.name仍然打印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;
}

没问题。 - Eugene Sh.
1个回答

4

我猜测字符串字面量“foo”并不绑定于复合字面量的生命周期,而是驻留在.rodata中?

是的。没错。在

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

当使用"foo"初始化指针时,就好像你在C语言中编写了以下代码:

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

C语言技术方面,严格来说,static不能用于复合文字(compound literals),而C的字符串字面量实际上是非正式的const-char数组,但它们的正式类型是没有constchar[] (由于奇怪的历史原因)。

但要小心使用。在C中,您可以使用字符串字面量初始化数组,如果.name是一个成员数组,则将“it”(其衰减指针)存储到全局变量中是不明智的。


1
它们可以是数组,也可以不是。例如:https://godbolt.org/z/K4esE8fqT 而且字面量也没有存储在rodata中。 - 0___________
2
C23将允许为复合字面量使用“static”存储。 - tstanisl
@0___________ 编译器就像薛定谔的盒子。除非有人决定传递它的地址,否则它既是数组又不是数组,然后它就成为了一个数组——尽管如果它们具有相同内容或一个是另一个字符串字面量的后缀,那么它可能会与另一个数组合并。 - Petr Skocik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接