为什么返回一个函数的引用本地值不是编译错误? [英] Why is returning a reference to a function local value not a compile error?

查看:1238
本文介绍了为什么返回一个函数的引用本地值不是编译错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码调用未定义的行为。

  int& foo()
{
int bar = 1234;
return bar;
}

g ++发出警告:




警告:引用局部变量'bar'返回[-Wreturn-local-addr]


clang ++ too:


警告:引用与局部变量'bar'相关的堆栈内存[-Wreturn-stack-address] / p>

为什么这不是编译错误(忽略 -Werror )? p>

是否有返回一个局部var的ref是有效的?



EDIT 正如所指出的,规范要求这是可编译的。那么,为什么规范不禁止这样的代码?

解决方案

我会说,要求这使程序不成型也就是说,使这是一个编译错误)将使标准复杂化很少的好处。



如果你指定的太少,它将会被删除。不太有用。编译器可能已经检查这是否会发出警告,真正的程序员用 -Wall_you_can_give_me -Werror 编译。



如果你指定的太多,编译器将很难(或不可能)实现标准。



考虑这个类(你只有头和库):

  class Foo 
{
int x;

public:
int& getInteger();
};

此代码:

  int& bar()
{
Foo f;
return f.getInteger();
}

现在,标准应该写成使这个不成形吗?可能不会,如果 Foo 如下实现:

  #include Foo.h

int global;

int& Foo :: getInteger()
{
return global;
}

同时,可以这样实现:

  #includeFoo.h

int& Foo :: getInteger()
{
return x;
}

这当然会给你一个悬挂的参考。



我的意思是,编译器不能真正知道返回一个引用是否OK,除了一些小的情况(返回一个引用到一个函数范围自动变量或非引用的参数类型)。我认为这不值得使标准复杂化。特别是因为大多数编译器已经警告这是一个执行质量问题。


The following code invokes undefined behaviour.

int& foo()
{
  int bar = 1234;
  return bar;
}

g++ issues a warning:

warning: reference to local variable ‘bar’ returned [-Wreturn-local-addr]

clang++ too:

warning: reference to stack memory associated with local variable 'bar' returned [-Wreturn-stack-address]

Why is this not a compile error (ignoring -Werror)?

Is there a case where returning a ref to a local var is valid?

EDIT As pointed out, the spec mandates this be compilable. So, why does the spec not prohibit such code?

解决方案

I would say that requiring this to make the program ill-formed (that is, make this a compilation error) would complicate the standard considerably for little benefit. You'd have to exactly spell out in the standard when such cases shall be diagnosed, and all compilers would have to implement them.

If you specify too little, it will not be too useful. And compilers probably already check for this to emit warnings, and real programmers compile with -Wall_you_can_give_me -Werror anyway.

If you specify too much, it will be difficult (or impossible) for compilers to implement the standard.

Consider this class (for which you only have the header and a library):

class Foo
{
  int x;

public:
  int& getInteger();
};

And this code:

int& bar()
{
  Foo f;
  return f.getInteger();
}

Now, should the standard be written to make this ill-formed or not? Probably not, what if Foo is implemented like this:

#include "Foo.h"

int global;

int& Foo::getInteger()
{
  return global;
}

At the same time, it could be implemented like this:

#include "Foo.h"

int& Foo::getInteger()
{
  return x;
}

Which of course would give you a dangling reference.

My point is that the compiler cannot really know whether returning a reference is OK or not, except for a few trivial cases (returning a reference to a function-scope automatic variable or parameter of non-reference type). I don't think it's worth it to complicate the standard for that. Especially as most compilers already warn about this as a quality-of-implementation matter.

这篇关于为什么返回一个函数的引用本地值不是编译错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆