首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >decltype(auto) foo()不加警告地返回本地引用

decltype(auto) foo()不加警告地返回本地引用
EN

Stack Overflow用户
提问于 2016-09-14 12:50:26
回答 1查看 381关注 0票数 10

在使用来自现代C++的示例时,我编写了以下代码。

代码语言:javascript
复制
#include <string>
#include <iostream>

static int count = 0;

class Counter
{
public:
    Counter() { ++count; };
    Counter(Counter& r) { ++count; };
    Counter(Counter&& r) { ++count; };
    ~Counter() { --count; };

    void foo() {};
};

decltype(auto) foo_warn()
{
    Counter c;
    return (c);             // Warning about returning local reference
}

decltype(auto) foo_no_warn()
{
    Counter c;
    return 1==1 ? c : c;    // No warning, still local reference returned
}

int main()
{
    Counter& a = foo_warn();
    Counter& b = foo_no_warn();

    std::cout << count << std::endl;  // prints 0

    a.foo();
    b.foo();

    return 0;
}

用命令编译的代码:

g++-6 -std=c++14 -Wall -O0 decl_fail.cpp -o decl_fail

输出:

代码语言:javascript
复制
g++-6 -std=c++14 -Wall -O0    decl_fail.cpp   -o decl_fail
decl_fail.cpp: In function ‘decltype(auto) foo_warn()’:
decl_fail.cpp:19:10: warning: reference to local variable ‘a’ returned [-Wreturn-local-addr]
  Counter a;
          ^

显然,decltype(auto)返回表达式的引用(但仍然不是直观的),因此ab是无效的引用(由count==0证明)。

问题是为什么编译器没有在foo_no_warn中警告我

我刚刚在编译器中发现了一个bug,还是这是一些可以解释的行为?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-19 20:47:45

首先,让我们声明这个问题与decltype(auto)没有显式关联,因为如果函数返回计数器&显式的话,您将得到几乎相同的结果。

您可以考虑以下代码:

代码语言:javascript
复制
typedef std::vector<int> Type;

class DataContainer {
public:
    DataContainer() : data(Type(1024, 0)) {}
    const Type& getData() const { return data; }

private:
    const Type data;
};

const Type& returnLocalRef()
{
    DataContainer container;
    const Type& data = container.getData();
    return data; // o! returning a ref to local - no warning for most compilers
}

尽管返回了一个本地引用,但编译器在VS2015或gcc48 (与-Wall一起)中都不会发出警告。但是,如果您从const & data中删除了引用,编译器就会立即发现问题。你认为这种行为是错误的吗?有争议的。

Compier的基本工作是编译代码。它提醒开发人员注意一些明显的问题,但在大多数情况下,它不会对程序逻辑进行更深入的分析(编译时间将受到影响)。这就是开发和使用代码静态分析工具的目的。

所描述的情况可以看作是一个简单的例子,但是一个级别的间接就足以“欺骗”编译器。因为要验证这一点,编译器需要检查从getData方法返回的实际内容。

做一个简单的修改:

代码语言:javascript
复制
Type globalData;
...
const Type& getData() const { return globalData; }

将使从returnLocalRef函数返回的引用有效。因此,这可以被认为是编译器在分析复杂性和时间效率之间的权衡。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39490912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档