【问题标题】:Ternary operator: Compiler does not emit return reference of local variable warning三元运算符:编译器不发出局部变量警告的返回引用
【发布时间】:2019-04-21 09:07:43
【问题描述】:

我在 C++ 中实现了一个简单的函数,它比较两个对象并返回它们的最大对象的引用增加了 1。我希望创建一个临时对象,当返回该对象的引用时,会发出警告由于临时对象的悬空引用,编译器将出现。但不会产生警告。我几乎不明白为什么会这样。

下面是我写的代码

#include <iostream>
#include <string>
class A
{
    public:
     A():v(0)
    {
         std::cout << "A::ctror" <<std::endl;
    }
    A (int const & x):v(v + x)
    {

        std::cout << "convertion::ctror(int)" << std::endl;

    }
    static  A  &   max(A  & x , A  & y)
    {
        return x.v > y.v ? (x+1) : (y +1  ) ;
    }
    A & operator +( A const a )
    {
        this->v+=a.v;
        return *this;
    }
    int v ;
};
int main()
{
 A a1;
 A a2;
 a1.v = 1;
 a2.v = 6;
 A const &  a3 =  A::max(a1,a2);
 std::cout << a3.v << std::endl;
}

【问题讨论】:

  • 这里没有悬空引用
  • @Kerndog73 为什么没有悬空引用? x+1 创建了一个引用返回的新对象A?是这样吗?
  • operator+ 返回一个引用。 a3 是对 a2 的引用。没有悬空参考
  • x+1 不会创建新对象。您的 operator+ 行为类似于 +=;它增加左操作数并返回对它的引用。
  • 你的A (int const &amp; x):v(v + x)构造函数坏了:它从v读取,这是一个未初始化的变量。

标签: c++ reference compiler-warnings ternary-operator


【解决方案1】:

至于您问题中的实际代码:没有创建临时对象,因为您的 maxoperator+ 都采用它们的参数并通过引用返回它们的结果。因此代码实际上是有效的(如果奇怪/误导)。

但是,如果我们将您的代码简化为实际包含错误的版本:

struct A
{
    static int &foo(int &x)
    {
        int a = 42;
        return x < a ? x : a;
    }
};

int main()
{
    int n = 0;
    return A::foo(n);
}

...我们仍然没有收到警告,至少在 g++ 8.3.1 中没有。

这似乎与 foo 作为成员函数和/或标记为 static 有关。没有类包装器:

static int &foo(int &x)
{
    int a = 42;
    return x < a ? x : a;
}

int main()
{
    int n = 0;
    return foo(n);
}

...仍然没有警告。

同样,没有static

struct A
{
    int &foo(int &x)
    {
        int a = 42;
        return x < a ? x : a;
    }
};

int main()
{
    A wtf;
    int n = 0;
    return wtf.foo(n);
}

...也没有警告。

但是没有类和static:

int &foo(int &x)
{
    int a = 42;
    return x < a ? x : a;
}

int main()
{
    int n = 0;
    return foo(n);
}
.code.tio.cpp: In function ‘int& foo(int&)’:
.code.tio.cpp:4:24: warning: function may return address of local variable [-Wreturn-local-addr]
     return x < a ? x : a;
                        ^

...正如预期的那样。

我怀疑这是 g++ 中的错误/疏忽。

实际上并不要求编译器对错误代码发出警告,但很遗憾没有诊断出相当明显的错误代码实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-06
    • 2016-11-08
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    相关资源
    最近更新 更多