Связана ли константная ссылка с другой ссылкой, созданной из временной свисающей ссылки? - PullRequest
0 голосов
/ 26 мая 2018

Ниже приведен фрагмент кода:

#include <iostream>
using namespace std;
struct B{
     int b;
     ~B(){cout <<"destruct B" << endl;}
};
B func(){
    B b;
    b.b = 1;
    return b;
}
int main(){
    const B& instance = (const B&)func(); //is `instance` a dangling reference?
    cout <<instance.b<<endl;
    return 0;
}

в этом онлайн-компиляторе вывод

destruct B
destruct B
1

Таким образом, возвращаемое значение кажется разрушенным раньше, чемcout операция.Таким образом, instance представляется висячей ссылкой.

Если мы изменим const B& instance = (const B&)func(); на const B& instance =func();, то результат будет

destruct B
1
destruct B

В качестве дополнения, если я протестируюкод в vs2015, то вывод является последним.Однако, если протестировано в gcc (до 4.6) , вывод будет первым, но последним в версии после 4.6.Поэтому я хочу знать, является ли онлайн-компилятор неправильным или ссылка на самом деле свисает.

1 Ответ

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

Согласно новейшему проекту [class.teven] / 6 (не относящаяся к делу часть исключена мной):

Третий контекст - это когда ссылка связана свременный объектВременный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъекта, к которому привязана ссылка, сохраняется в течение всего времени жизни ссылки, если значение glvalue, к которому привязана ссылка, было получено с помощью одного из следующих:

  • ...

  • a const_cast ([expr.const.cast]), static_cast ([expr.static.cast]), dynamic_cast ([expr.dynamic.cast]) или reinterpret_cast ([expr.reinterpret.cast]), преобразующий без определяемого пользователем преобразования операнд glvalue, который является одним из этих выражений, в glvalue, который ссылается на обозначенный объектоперандом или его полным объектом или подобъектом,

  • ...

... [Примечание: явный типпреобразование ([expr.type.conv], [expr.cast]) интерпретируется как последовательность элементарных приведений, описанных выше.[Пример:

const int& x = (const int&)1;  // temporary for value 1 has same lifetime as x

- конец примера] - конец заметки]

Ваш код правильно сформирован.


До C ++ 14, формулировка в стандарте неясна для такого случая, и есть проблема с дефектом 1376 .Эта проблема проясняет срок жизни временного объекта, который должен не быть продлен в таком случае.Однако это пояснение заменено вопросом 1299 (разрешение которого не включено даже в C ++ 17, но в текущий проект).

Таким образом, вы можете сделать вывод, что до разрешения проблемы 1299 , это ошибка для GCC с версией после 4.6.Существует также отчет об ошибке 52202 для GCC.

...