【问题标题】:returning reference to local temporary object on pointer dereferencing在指针取消引用时返回对本地临时对象的引用
【发布时间】:2015-11-16 13:34:42
【问题描述】:

Clang 编译器在编译此代码 sn-p 时产生警告,我不知道为什么。

const int* Get() {
    static const int ARRAY[4] = {1, 2, 3, 4};
    return &ARRAY[0];
}

const int& Test() {
    const auto& p = Get();
    return (*p);
}

warning: returning reference to local temporary object [-Wreturn-stack-address] 
    return (*p);

GCC 在此代码上没有显示警告。 我可以像这样修复 sn-p:const auto p = Get(); 但我想知道是否有一些临时对象并且问题更深层次

【问题讨论】:

  • @101010 “临时对象”?也许你可以更清楚一点?我们绝对可以在堆栈中引用非常量变量。
  • p 是临时的,*p 是有效的。我认为这是 Clang 的误报。
  • @JonathanMee: Learn about temporaries
  • @LightnessRacesinOrbit 这是一本很好的读物,现在我已经开始阅读了,谢谢。

标签: c++ reference return compiler-warnings clang++


【解决方案1】:

该警告是误报,因为 p 的指针不是临时的,尽管 p 指的是一个。在更多情况下,该警告是虚假产生的;参见例如Bug 21218,它使用

char * f() {
    typedef char* t;
    const t & r = new char[5];
    return r;
}

如果返回类型是引用,Clang 会在返回的表达式中查找 const-references(已绑定到临时变量),而不考虑它们的使用方式。

【讨论】:

    【解决方案2】:

    答案:Clang 的警告不正确。

    让我们逐步了解这里发生的事情:

    1. static const int ARRAY[4] = {1, 2, 3, 4}; 构造一个由ints 组成的全局数组
    2. return &ARRAY[0]; 返回指向全局数组第一个元素的指针
    3. const auto& p = Get() 存储对指向全局数组第一个元素的指针的引用
    4. return (*p); 创建对全局数组第一个元素的左值的引用

    4 是一个棘手的问题。 Clang 似乎错误地认为 *p 是一个局部值,而实际上我们知道它是一个全局值。

    这个证明的关键是the fact that *p returns an lvalue

    【讨论】:

    • “这很容易做到”,因为它在标准中说得很清楚。
    • @LightnessRacesinOrbit 我自己没有标准的副本,而且我似乎找不到任何在线信息来确认取消引用运算符返回了左值。如果您能指出我希望包含它的来源,而不是证明我的答案的示例。
    • 或5.3.1/1 C++14第一句
    • @LightnessRacesinOrbit 谢谢我已经找到了……尽管它是维基百科 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多