我了解了函数调用之间的return值,
并尝试了以下代码片段:

/* file structaddr.c */
#include <stdio.h>
#define MSIZE 10

struct simple
{
    char c_str[MSIZE];
};
struct simple xprint(void)
{
    struct simple ret = { "Morning !" };
    return ret;
}
int main(void)
{
    printf("Good %s\n", xprint().c_str);
    return 0;
}

该代码的编译没有错误和警告。
使用GCC 4.4.3(Ubuntu 4.4.3-4ubuntu5.1)和Visual C++编译器进行了测试。
 gcc -m32 -std=c99 -Wall -o test  structaddr.c
 cl -W3 -Zi -GS -TC -Fetest structaddr.c

输出 :
早上好 !

我对结果有些困惑。
代码编写正确吗?

我的问题 :
  • 函数return value(
    上例中的struct),以及如何正确访问它们?
  • 哪里结束return值的生存期?
  • 最佳答案

    在C语言中,当printf表达式完成时,示例中的临时项的生存期结束:

  • Per C 2011(N1570)6.2.4 8,当包含临时表的完整表达式(或声明符)的求值结束时,临时表的生存期结束:“具有结构或 union 类型的非左值表达式,其中结构或 union 包含具有数组类型的成员(递归包括所有包含的结构和 union 的成员)是指具有自动存储期限和临时生存期的对象。它的生命周期从对表达式求值开始,并且其初始值是表达式的值。当包含完整表达式或完整声明符的求值结束时,其生存期结束。”
  • 每6.8 4:“完整表达式是不属于另一个表达式或声明符的表达式。”根据6.7.6 3:“完整的声明符是不属于另一个声明符的声明符。”
  • 因此,您的示例中的临时生存期将在printf表达式完成时结束。

  • 在C++中,示例中的生存期与C中相同:
  • Per C++ 2010(N3092)12.2 3:“临时对象被销毁是评估(按词法)包含创建点的完整表达式(1.9)的最后一步。”
  • 每12.2 4和5:“在两种情况下,临时变量在与完整表达式结束时不同的位置被销毁。第一个上下文是调用默认构造函数初始化数组的元素时。如果构造函数具有一个或多个默认参数,则在构造下一个数组元素(如果有)之前,将对在默认参数表达式中创建的每个临时变量的销毁顺序进行排序。” “第二种情况是引用绑定(bind)到临时目录。引用所绑定(bind)的临时对象或引用所绑定(bind)的子对象的完整对象的临时对象在引用的有效期内一直存在,但以下情况除外:…”(为简洁起见,我省略了这些异常(exception),因为它们不适用在这里。)
  • 因此,您的示例在C++中是相同的,临时对象作为评估printf表达式的最后一步而被销毁。
  • 关于c - 函数返回值的生存期是多少?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17902045/

    10-11 19:34