从函数返回对局部变量的引用

时间:2021-12-23 16:45:04

I have some questions on returning a reference to a local variable from a function:

我有一些关于从函数返回对局部变量的引用的问题:

class A
{
public:
        A(int xx):x(xx)
 {
  printf("A::A()\n");
 }
};

const A& getA1()
{
 A a(5);
 return a;
}

A& getA2()
{
 A a(5);
 return a;
}

A getA3()
{
 A a(5);
 return a;
}

int main()
{ 
     const A& newA1 = getA1(); //1
     A& newA2 = getA2();       //2
     A& newA3 = getA3();       //3
}

My questions are =>

我的问题是= >

  1. Is the implementation of getA1() correct? I feel it is incorrect as it is returning the address of a local variable or temporary.

    getA1()的实现是否正确?我认为它是不正确的,因为它返回的是局部变量或临时变量的地址。

  2. Which of the statements in main (1,2,3) will lead to undefined behavior?

    主(1,2,3)中的哪个语句会导致未定义的行为?

  3. In const A& newA1 = getA1(); does the standard guarantee that a temporary bound by a const reference will not be destroyed until the reference goes out of scope?

    在const a&newa1 = getA1()中;该标准是否保证在引用超出范围之前不会销毁受const引用约束的临时绑定?

4 个解决方案

#1


31  

1. Is getA1() implementation correct ? I feel it is incorrect as it is returning address of local variable or temporary.

1。getA1()实现正确吗?我觉得它是不正确的,因为它是返回本地变量或临时变量的地址。

The only version of getAx() that is correct in your program is getA3(). Both of the others have undefined behaviour no matter how you use them later.

在程序中唯一正确的getAx()版本是getA3()。其他两个都有未定义的行为,不管您以后如何使用它们。

2. Which of the statements in main ( 1,2,3) will lead to undefined behavior ?

2。主(1,2,3)中的哪个语句会导致未定义的行为?

In one sense none of them. For 1 and 2 the undefined behaviour is as a result of the bodies of the functions. For the last line, newA3 should be a compile error as you cannot bind a temporary to a non const reference.

从某种意义上说,他们都不是。对于1和2,未定义的行为是函数体的结果。对于最后一行,newA3应该是一个编译错误,因为您不能将临时引用绑定到非const引用。

3. In const A& newA1 = getA1(); does standard guarantees that temporary bound by a const reference will not be destroyed until the reference goes out of scope?

3所示。在const a&newa1 = getA1()中;标准是否保证在引用超出范围之前不会被销毁?

No. The following is an example of that:

不。下面是一个例子:

A const & newConstA3 = getA3 ();

Here, getA3() returns a temporary and the lifetime of that temporary is now bound to the object newConstA3. In other words the temporary will exist until newConstA3 goes out of scope.

在这里,getA3()返回一个临时值,该临时值的生存期现在绑定到对象newConstA3。换句话说,临时协议将一直存在,直到newConstA3超出范围。

#2


4  

Q1: Yes, this is a problem, see answer to Q2.

Q1:是的,这是一个问题,参见Q2的答案。

Q2: 1 and 2 are undefined as they refer to local variables on the stack of getA1 and getA2. Those variables go out of scope and are no longer available and worse can be overwritten as the stack is constantly changing. getA3 works since a copy of the return value is created and returned to the caller.

Q2: 1和2是没有定义的,因为它们指的是getA1和getA2堆栈上的局部变量。这些变量超出了范围,不再可用,更糟糕的是,当堆栈不断变化时,可以覆盖它们。getA3工作是因为创建了返回值的副本并返回给调用者。

Q3: No such guarantee exists to see answer to Q2.

问题3:没有这样的保证可以看到问题的答案。

#3


2  

I think the main problem is that you are not returning temporaries at all, you should

我认为主要的问题是你根本就不返回临时职位,你应该

return A(5);

rather than

而不是

A a(5);
return a;

Otherwise you are returning local variable address, not temporary. And the temporary to const reference only works for temporaries.

否则将返回本地变量地址,而不是临时地址。临时引用仅适用于临时引用。

I think its explained here: temporary to const reference

我想它的解释是:暂时引用。

#4


0  

If you will compile this on VC6 you will get this warning

如果您将在VC6上编译它,您将得到这个警告

******Compiler Warning (level 1) C4172 returning address of local variable or temporary A function returns the address of a local variable or temporary object. Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid.******

******编译器警告(级别1)C4172本地变量或临时函数的返回地址返回本地变量或临时对象的地址。当函数返回时,将销毁本地变量和临时对象,因此返回的地址无效

While testing for this problem i found interesting thing (given code is working in VC6):

在测试这个问题时,我发现了有趣的事情(给定代码在VC6中工作):

 class MyClass
{
 public:
 MyClass()
 {
  objID=++cntr;
 }
MyClass& myFunc()
{
    MyClass obj;
    return obj;
}
 int objID;
 static int cntr;
};

int MyClass::cntr;

main()
{
 MyClass tseadf;
 cout<<(tseadf.myFunc()).objID<<endl;

}

#1


31  

1. Is getA1() implementation correct ? I feel it is incorrect as it is returning address of local variable or temporary.

1。getA1()实现正确吗?我觉得它是不正确的,因为它是返回本地变量或临时变量的地址。

The only version of getAx() that is correct in your program is getA3(). Both of the others have undefined behaviour no matter how you use them later.

在程序中唯一正确的getAx()版本是getA3()。其他两个都有未定义的行为,不管您以后如何使用它们。

2. Which of the statements in main ( 1,2,3) will lead to undefined behavior ?

2。主(1,2,3)中的哪个语句会导致未定义的行为?

In one sense none of them. For 1 and 2 the undefined behaviour is as a result of the bodies of the functions. For the last line, newA3 should be a compile error as you cannot bind a temporary to a non const reference.

从某种意义上说,他们都不是。对于1和2,未定义的行为是函数体的结果。对于最后一行,newA3应该是一个编译错误,因为您不能将临时引用绑定到非const引用。

3. In const A& newA1 = getA1(); does standard guarantees that temporary bound by a const reference will not be destroyed until the reference goes out of scope?

3所示。在const a&newa1 = getA1()中;标准是否保证在引用超出范围之前不会被销毁?

No. The following is an example of that:

不。下面是一个例子:

A const & newConstA3 = getA3 ();

Here, getA3() returns a temporary and the lifetime of that temporary is now bound to the object newConstA3. In other words the temporary will exist until newConstA3 goes out of scope.

在这里,getA3()返回一个临时值,该临时值的生存期现在绑定到对象newConstA3。换句话说,临时协议将一直存在,直到newConstA3超出范围。

#2


4  

Q1: Yes, this is a problem, see answer to Q2.

Q1:是的,这是一个问题,参见Q2的答案。

Q2: 1 and 2 are undefined as they refer to local variables on the stack of getA1 and getA2. Those variables go out of scope and are no longer available and worse can be overwritten as the stack is constantly changing. getA3 works since a copy of the return value is created and returned to the caller.

Q2: 1和2是没有定义的,因为它们指的是getA1和getA2堆栈上的局部变量。这些变量超出了范围,不再可用,更糟糕的是,当堆栈不断变化时,可以覆盖它们。getA3工作是因为创建了返回值的副本并返回给调用者。

Q3: No such guarantee exists to see answer to Q2.

问题3:没有这样的保证可以看到问题的答案。

#3


2  

I think the main problem is that you are not returning temporaries at all, you should

我认为主要的问题是你根本就不返回临时职位,你应该

return A(5);

rather than

而不是

A a(5);
return a;

Otherwise you are returning local variable address, not temporary. And the temporary to const reference only works for temporaries.

否则将返回本地变量地址,而不是临时地址。临时引用仅适用于临时引用。

I think its explained here: temporary to const reference

我想它的解释是:暂时引用。

#4


0  

If you will compile this on VC6 you will get this warning

如果您将在VC6上编译它,您将得到这个警告

******Compiler Warning (level 1) C4172 returning address of local variable or temporary A function returns the address of a local variable or temporary object. Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid.******

******编译器警告(级别1)C4172本地变量或临时函数的返回地址返回本地变量或临时对象的地址。当函数返回时,将销毁本地变量和临时对象,因此返回的地址无效

While testing for this problem i found interesting thing (given code is working in VC6):

在测试这个问题时,我发现了有趣的事情(给定代码在VC6中工作):

 class MyClass
{
 public:
 MyClass()
 {
  objID=++cntr;
 }
MyClass& myFunc()
{
    MyClass obj;
    return obj;
}
 int objID;
 static int cntr;
};

int MyClass::cntr;

main()
{
 MyClass tseadf;
 cout<<(tseadf.myFunc()).objID<<endl;

}