6

我阅读了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值(上例中的数组 )的可见性是什么struct,以及如何正确访问它们?

  • 价值的生命周期在哪里结束return

4

2 回答 2

9

在 C 中,示例中的临时变量的生命周期在printf表达式完成时结束:

  • 根据 C 2011 (N1570) 6.2.4 8,当包含它的完整表达式(或声明符)的评估结束时,临时的生命周期结束:“具有结构或联合类型的非左值表达式,其中结构或联合包含具有数组类型的成员(递归地包括所有包含的结构和联合的成员)指的是具有自动存储持续时间和临时生命周期的对象。它的生命周期从计算表达式时开始,它的初始值是表达式的值。当包含完整表达式或完整声明符的评估结束时,它的生命周期结束。”</li>
  • 根据 6.8 4:“完整表达式是不属于另一个表达式或声明符的一部分的表达式。” 根据 6.7.6 3:“完整的声明器是不属于另一个声明器的声明器。”</li>
  • 因此,示例中临时变量的生命周期在printf表达式完成时结束。

在 C++ 中,您的示例中的生命周期与 C 中的相同:

  • 根据 C++ 2010 (N3092) 12.2 3:“临时对象被销毁作为评估完整表达式 (1.9) 的最后一步,该完整表达式 (从词法上) 包含它们的创建点。”</li>
  • 根据 12.2 4 和 5:“在两种情况下,临时对象在与完整表达式结尾不同的点被销毁。第一个上下文是调用默认构造函数来初始化数组元素时。如果构造函数有一个或多个默认参数,则在默认参数表达式中创建的每个临时变量的销毁都将在构造下一个数组元素(如果有)之前进行排序。” “第二个上下文是当一个引用绑定到一个临时的。引用绑定的临时对象或引用绑定的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:...”(为简洁起见,我省略了例外情况,因为它们不适用这里。)
  • 因此,您的示例在 C++ 中是相同的,临时对象在评估printf表达式的最后一步被销毁。
于 2013-07-27T23:08:52.407 回答
2

函数xprint返回一个结构的副本,编译器将这个副本存储在一个临时文件中,临时文件的生命周期就是printf函数调用的持续时间。当printf函数返回时,该临时对象被销毁。

于 2013-07-27T20:28:42.010 回答