Тернарный оператор: компилятор не отправляет ссылку на предупреждение о локальной переменной - PullRequest
0 голосов
/ 21 апреля 2019

Я реализовал простую функцию в 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;
}

1 Ответ

3 голосов
/ 21 апреля 2019

Что касается фактического кода в вашем вопросе: никакие временные объекты не создаются, потому что ваши max и operator+ принимают свои аргументы и возвращают свои результаты по ссылке. Таким образом, код действительно действителен (если он странный / вводящий в заблуждение).

Однако, если мы упростим ваш код до версии, которая фактически содержит ошибку:

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 ++.

Компиляторы на самом деле не обязаны предупреждать о плохом коде, но, к сожалению, довольно очевидный случай неработающего кода не диагностируется.

...