c ++ простая функция типа ссылок - PullRequest
0 голосов
/ 21 февраля 2012
int& lameness()
{
    int h=66;
    return h;
}
int main()
{

    int c;
    c = lameness();
    cout<<"c is "<<c<< endl;
    system("pause");
    return 0;
}

Почему это работает? int h является локальной переменной и не должен быть уничтожен после выхода из области видимости функции?

Если я изменю свою функцию на это, она будет работать без предупреждения. Это безопаснее в любом случае? :

int& lameness()
{
    int h=66;
    int &a = h;
    return a;
}

Ответы [ 5 ]

4 голосов
/ 21 февраля 2012

Да.Но замечательная вещь в неопределенном поведении состоит в том, что на самом деле происходит ... неопределенное.Уничтожение int на самом деле вообще не подразумевает никаких действий, поэтому, если ничто не будет повторно использовать это место в стеке, значение все равно останется.Вот что делает подобные вещи такими разочаровывающими - часто кажется, что это работает, пока вы не сделаете небольшое, казалось бы, не связанное изменение, и оно перестает работать!

2 голосов
/ 21 февраля 2012

По совпадению работает, проверьте:

По сути, он вернул правильное значение, поскольку память все еще была установлена ​​на это значение. Иногда в будущем это может быть не так. Не делай этого.

1 голос
/ 21 февраля 2012

Это работает только для вас по совпадению, и потому что ваш код берет копию значения в ссылке, прежде чем делать что-либо еще.Он не гарантированно работает.

Вы можете увидеть, что он не работает с:

#include <iostream>
using namespace std;
int& lameness()
{
    int h=66;
    return h;
}
int main()
{
    int &c = lameness();
    cout << "c is " << c << endl;
    return 0;
}

Конечно, мне пришлось игнорировать предупреждения компиляции:

x.cpp: In function ‘int& lameness()’:
x.cpp:5:13: warning: reference to local variable ‘h’ returned [enabled by default]
x.cpp: In function ‘int main()’:
x.cpp:12:28: warning: ‘h’ is used uninitialized in this function [-Wuninitialized]

Выводбыло:

c is 0

Это происходит потому, что к моменту передачи c в систему ввода-вывода пространство, которое когда-то было h в lameness(), уже использовалось для других переменных, поэтому царапины66, который был сохранен в пространстве.На самом деле, даже ваш оригинальный код выдает 0 на моем компьютере.

1 голос
/ 21 февраля 2012

уничтожено.Это работает, потому что память, в которой был сохранен h, не была перезаписана к моменту печати значения.

1 голос
/ 21 февраля 2012

не работает. Это неопределенное поведение. Ваш скептицизм был прав: функция lameness является ошибкой, и некоторые компиляторы отметили бы ее как таковую. Тем не менее, компилятор может «соответствовать» и все же «разрешать» этот код ... такова «хромота» C и C ++.

...