在指针解除引用时返回对本地临时对象的引用

时间:2015-11-16 13:34:43

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

Clang编译器生成警告,编译此代码片段,我无法弄清楚原因。

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没有显示此代码的警告。 我可以修复这样的片段:const auto p = Get(); 但我想知道是否有一些临时对象,问题更深层次

2 个答案:

答案 0 :(得分:6)

该警告是误报,因为p的指针不是临时的,尽管p指的是char * f() { typedef char* t; const t & r = new char[5]; return r; } 。有更多的情况会发出虚假的警告;参见例如Bug 21218,使用

 <nav class="navbar navbar-fixed-top navbar-light bg-faded">

                        <!-- Toggle Button -->
                        <button class="navbar-toggler hidden-sm-up" type="button" data-toggle="collapse" data-target="#nav-content">
                            ☰
                        </button>

                        <!-- Nav Content -->
                        <div class="collapse navbar-toggleable-xs" id="nav-content">
                            <a class="navbar-brand" href="">MIGRATE</a>
                            <ul class="nav navbar-nav pull-right">

                                <li class="nav-item active">
                                    <a class="nav-link scrollto" href="#home">Home</a>
                                </li>

                                <li class="nav-item">
                                    <a class="nav-link scrollto" href="#grid">Grid System</a>
                                </li>


                                <li class="nav-item">
                                    <a class="nav-link scrollto" href="#tooltips">Tooltips</a>
                                </li>


                                <li class="nav-item">
                                    <a class="nav-link scrollto" href="#tables">Tables</a>
                                </li>



                                <li class="nav-item">
                                    <a class="nav-link scrollto" href="#carousel">Carousel</a>
                                </li>


                                <li class="nav-item">
                                    <a class="nav-link scrollto" href="#cards">Cards</a>
                                </li>


                                <li class="nav-item">
                                    <a class="nav-link scrollto" href="#forms">Forms</a>
                                </li>

                            </ul>
                        </div>

                    </nav>

据推测,如果返回类型是引用,Clang会在返回的表达式中查找const-references(已绑定到temporaries),而不考虑它们是如何被使用的。

答案 1 :(得分:1)

答案:Clang的警告不正确。

让我们逐步完成这里发生的事情:

  1. static const int ARRAY[4] = {1, 2, 3, 4};构建一个int s
  2. 的全局数组
  3. return &ARRAY[0];返回指向全局数组
  4. 的第一个元素的指针
  5. const auto& p = Get()存储对指向全局数组的第一个元素的指针的引用
  6. return (*p);创建对全局数组的第一个元素的左值的引用
  7. 4 是棘手的。 Clang似乎错误地认为*p是本地值,而事实上我们知道它是全局的。

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