c - 不含数组的结构体的生命周期

标签 c struct scope return lifetime

获取此代码:

#include <stdio.h>

struct S { int x; int y; };

struct S foo(int a, int b) {
    struct S s = { a, b };
    return s;
}

int main() {
    int a;

    a = foo(2, 4).x;
    printf("%d\n", a);
    return 0;
}

它按预期工作。我关心的是返回的结构对象的生命周期。我知道标准讨论了包含数组的结构的临时生命周期,但在这种情况下,结构中没有数组。

所以我猜一旦foo()结束,它的返回值应该就死了,对吧?但显然我们仍然可以访问 x 成员。为什么?

最佳答案

"I know the standard talks about temporary lifetime for structs that contain arrays, but in this case there is no array in the structure."

你指的是这一段:

A non-lvalue expression with structure or union type, where the structure or union contains a member with array type (including, recursively, members of all contained structures and unions) refers to an object with automatic storage duration and temporary lifetime.36) Its lifetime begins when the expression is evaluated and its initial value is the value of the expression. Its lifetime ends when the evaluation of the containing full expression ends. Any attempt to modify an object with temporary lifetime results in undefined behavior. An object with temporary lifetime behaves as if it were declared with the type of its value for the purposes of effective type. Such an object need not have a unique address.

36) The address of such an object is taken implicitly when an array member is accessed.

Source: ISO/IEC 9899:2018 (C18), §6.2.4/8

临时生命周期是在包含数组成员的结构和 union 的上下文中明确发明的,因为从array to pointer decay开始,通过名称访问数组成员将为您提供指向数组第一个元素的指针,这在 C11 中添加此段落之前调用了早期 C 标准中未定义的行为。

克里斯·多德 (Chris Dodd) 解释得更好一点 here .

因此,临时生命周期(如标准中的含义)与具有非数组成员的结构无关。

"So I guess that as soon as foo() has ended, its return value should be dead, right?"

没有。 foo() 返回 struct S 对象的副本,而不是对本地 struct S 对象的引用。请注意,foo() 的返回类型是 struct S,而不是 struct S *(指向 struct S 的指针) >).

"But apparently we can still access the x member. Why?"

因为您向调用者返回了一份副本。您尝试访问此副本的成员 x,而不是 foo() 内的 struct S 对象 s .

关于c - 不含数组的结构体的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63575438/

相关文章:

Javascript - "this"范围问题修复

c++ - 函数返回时变量会超出范围吗?

无法在字符数组中 scanf '-' 或 '+'

objective-c - 检测内存增长

检查两个整数数组是否具有相同的元素,无论它们的顺序如何

swift 结构 : adding new parameters at runtime

c - 将宏扩展为多于一行

c - 将文本文件中的值扫描到结构中

c - 灵活的数组成员是否会增加结构的大小?

c++ - 绕过定义时如何使用变量?