getsoubl
getsoubl

Reputation: 1055

Ternary operator: Compiler does not emit return reference of local variable warning

I have implemented a naive function in C++ which compares two objects and returns a reference of the max object of them increased by 1. I expect that a temporal object is created and when a reference of this object is returned, a warning of the compiler will be appeared due to a dangling reference of the temporary object. But no warning is generated. I hardly understand why this happens.

Below is the code that I have written

#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;
}

Upvotes: 0

Views: 71

Answers (1)

melpomene
melpomene

Reputation: 85767

As for the actual code in your question: No temporary objects are created because both your max and operator+ take their arguments and return their results by reference. Thus the code is actually valid (if weird / misleading).

However, if we simplify your code to a version that actually contains a bug:

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

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

... we still don't get a warning, at least not with g++ 8.3.1.

This seems to be related to foo being a member function and/or marked static. Without the class wrapper:

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

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

... there is still no warning.

Similarly, without 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);
}

... no warning either.

But without the class and 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;
                        ^

... as expected.

I suspect this is a bug/oversight in g++.

Compilers aren't actually required to warn for bad code, but it seems unfortunate that a fairly obvious instance of broken code is not diagnosed.

Upvotes: 3

Related Questions