Объект возвращен без ключевого слова возврата - PullRequest
0 голосов
/ 08 мая 2018

Я что-то пробовал, и я сделал этот код: http://cpp.sh/4x435 (Показанный здесь ниже тоже)

#include <iostream>

using namespace std;

class Thing{
    public:
        int height;
        Thing(int h): height(h) {};
        Thing(): height(10) {};
        ~Thing(){};

        int display(){ return this->height; }
};

Thing* get(){
    Thing* x = new Thing(33);
}

int main(){
    Thing* a = new Thing();
    std::cout<<"1: "<<a->display()<<std::endl;
    a = get();
    std::cout<<"2: "<<a->display()<<std::endl;
    return 0;
}

Я забыл добавить возврат в функцию "get" до того, как скомпилировал и запустил ее, удивительно, что она все равно корректно сыграла (т. Е. Вывод 1: 10, 2: 33).

Теперь я увидел, что в онлайн-оболочке она отображает только «1: 10», тогда как, когда я пытаюсь заставить ее возвращать int или строку по значению, вот так:

int get(){ int a = 30; }

int main(){
    int b = get();
    std::cout<<"1: "<<b<<std::endl;
    return 0;
}

работает неправильно (выводит «1: 1»), это ожидаемо.

Что там происходит? Не должно ли "Things* get()" дать сбой, вызвать ошибку или, по крайней мере, заставить его выплюнуть какую-нибудь тарабарщину на экран или что-то еще?

Я использую Code :: Blocks 16.01, C ++ 11, GNU GCC Compiler, дополнительные флаги не установлены (поэтому только те, которые уже установлены Code :: Blocks)

EDIT:

Это не совсем то же самое, что предложенный дубликат, потому что пример int get() { int a = 30; } возвращает 1, если бы он возвратил 30, тогда это была бы та же проблема.

Однако я попробовал это:

int* get(){
    int* x = new int(4);
}
int main(){
    int* a;
    a = get();
    std::cout<<"2: "<<*a<<std::endl;
    return 0;
}

И здесь я получаю ту же проблему, что и при попытке попробовать первую версию кода, где get() имел тип возврата Thing*. Так что, похоже, это связано с указателями.

1 Ответ

0 голосов
/ 14 мая 2018

Используйте параметр -Wall при компиляции, чтобы получить соответствующее предупреждение, например:

gcc program.c -o program -Wall

В противном случае этот вопрос и его принятый ответ объясняют, почему это происходит, даже приводя пример, аналогичный вашему наблюдению:

Почему выпадение из конца непустой функции без возврата значения не приводит к ошибке компилятора?

Если вам интересно, проверьте вывод на ассемблере! Вы можете сгенерировать его:

gcc program.c -S

Поскольку поведение не определено, может произойти все, что вы испытываете, скорее всего, вызвано тем, что внутри функции, компилятор оставил правильное значение в регистре, обычно используемом для возврата.

...