Информация об изменениях

Сообщение Re[11]: Правомерно ли такое от 25.08.2020 11:04

Изменено 25.08.2020 11:05 Маркуша Шулин

Re[11]: Правомерно ли такое
Перейти к содержимому
Gmail используется с программой чтения с экрана
Meet
Начать встречу
Перейти на встречу
Hangouts

1 из 788
rsdncpp
Входящие
x

Oleg Labutin <ol.labutin@gmail.com>
22 авг. 2020 г., 13:23 (3 дня назад)
кому: я

Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, ollv, Вы писали:


O>> Так погоди. Давай я сначала попробую сказать точнее, почему я связываю кейсы

O>>
O>>  type& v = getrvalue();
O>>  call(getrvalue(), ...);
O>>


BFE>По моим представлением эти два выражения ничем не отличаются с точки зрения жизни временных объектов. Оба временных объекта должны дожить, условно говоря, "до точки с запятой".


Вот этимологически как оно было.
https://stackoverrun.com/ru/q/6489490

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

The word const was never present in this section. The rule has always been (from as long as I can remember) that a temporary used to initialize a reference has its lifetime extended to match that of the reference, regardless of the type of the reference.

И, кстати, говорят о продлении lifetime


BFE>Я не совсем понимаю зачем нужно расписывать в стандарте "продление жизни" если прямо сказано, что:

BFE>

BFE>Temporary objects are destroyed as the last step in evaluating the full-expression

Меня вот это и смущает ) то, что мы то ссылаемся на стандарт, то "это проблемы стандарта" ))

BFE>Можно же написать: getrvalue().print();. Тут тоже есть "продление жизни"?

материализация временного объекта, и продление жизни до full-expression. без точки темпорари не создастся. только вот тут момент, опять таки из области синт анализа. Подозреваю, что само понятие full-expression идет именно из грамматики что-то типа
full-expression-body : expression | expression end-of-block full-expression-body
full-expression : full-expression-body end-of-scope

BFE>Видимо из-за этой путаницы терминологии я ничего не понимаю. Есть выражения разных категорий. Они (выражения) могут либо порождать временные объекты, либо нет. Если временные объекты были материализованы, то можно говорить о времени их жизни. Зачем при этом привязывать время жизни временного объекта к категории выражения мне совершенно не понятно. Это же независимые понятия.

Глядя на стандарт и диаграммку

expression
| glvalue rvalue
| | lvalue xvalue prvalue

Возникают смутные сомнения, что скопипащено оно было с некоей грамматики. Отсюда и это странное смешение — rvalue и выражения. Хотя вот эти ветвления скорее обоснованы структурами синтаксического разбора,

O>>>>Объект — это уже физика языка, так вот живет объект как rvalue, выражением в данном случае будет именно std::vector<int>() -> arg, вот здесь оно и умрет, после инициализации параметра.

BFE>>>Выражение умрёт? Или умрёт объект?
O>> Давай так ) если считать, что мы принимаем связывание rvalue с простой ссылкой, то работает это правило
O>>
 (6.9) — A temporary object bound to a reference parameter in a function call (7.6.1.2) persists until the
O>>completion of the full-expression containing the call.

BFE>Зачем нужна эта сентенция, если утверждение процитированное выше —
Так она с дополнением )) "если считать, что мы принимаем связывание rvalue с простой ссылкой, то работает это правило ...". И именно так оно и должно звучать (имхо) в практических руководствах.
на этом компиляторе видно как работает в данном случае студийный компилятор. тут простой референс ведет себя как константный.
https://rextester.com/l/cpp_online_compiler_visual

#include <iostream>

static int count__ = 0;

struct class_type {
    class_type() {
       ++count__;
    }
    
    class_type(class_type const& ) { ++count__; }
    ~class_type() { --count__; }
    
    void foo(class_type const&, class_type, class_type&) {
         std::cout << "objects: " << count__ << std::endl;
    }
};

int main()
{
    {
        class_type& c0 = class_type();
        c0.foo(class_type(), class_type(), class_type());
        {
            class_type& c1=class_type();
            c1.foo(class_type(), class_type(), class_type());
        }
        c0.foo(class_type(), class_type(), class_type());
    }
    std::cout << "objects: " << count__ << std::endl;
}



O>>>> И если арг не проинициализируется от рвелью и не продлит жизнь объекту, он умрет.

BFE>>>Если арг не проинициализируется, то и функция вызвана не будет. Причём тут продление жизни для ссылок?
O>> так именно. "если проинициализируется и продлит жизнь". А то может ведь и не продлить (получим битую ссылку в теле)
BFE>Я не могу придумать конструкцию вызова функции без инициализации аргумента.

Но я не про инициализацию говорил, я говорил про потенциальную вероятность того, что ссылка окажется битая, т/к каким-то образом не произойдет материализация временного объекта (т/к там просто референс)
Re[11]: Правомерно ли такое
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, ollv, Вы писали:


O>> Так погоди. Давай я сначала попробую сказать точнее, почему я связываю кейсы

O>>
O>>  type& v = getrvalue();
O>>  call(getrvalue(), ...);
O>>


BFE>По моим представлением эти два выражения ничем не отличаются с точки зрения жизни временных объектов. Оба временных объекта должны дожить, условно говоря, "до точки с запятой".


Вот этимологически как оно было.
https://stackoverrun.com/ru/q/6489490

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

The word const was never present in this section. The rule has always been (from as long as I can remember) that a temporary used to initialize a reference has its lifetime extended to match that of the reference, regardless of the type of the reference.

И, кстати, говорят о продлении lifetime


BFE>Я не совсем понимаю зачем нужно расписывать в стандарте "продление жизни" если прямо сказано, что:

BFE>

BFE>Temporary objects are destroyed as the last step in evaluating the full-expression

Меня вот это и смущает ) то, что мы то ссылаемся на стандарт, то "это проблемы стандарта" ))

BFE>Можно же написать: getrvalue().print();. Тут тоже есть "продление жизни"?

материализация временного объекта, и продление жизни до full-expression. без точки темпорари не создастся. только вот тут момент, опять таки из области синт анализа. Подозреваю, что само понятие full-expression идет именно из грамматики что-то типа
full-expression-body : expression | expression end-of-block full-expression-body
full-expression : full-expression-body end-of-scope

BFE>Видимо из-за этой путаницы терминологии я ничего не понимаю. Есть выражения разных категорий. Они (выражения) могут либо порождать временные объекты, либо нет. Если временные объекты были материализованы, то можно говорить о времени их жизни. Зачем при этом привязывать время жизни временного объекта к категории выражения мне совершенно не понятно. Это же независимые понятия.

Глядя на стандарт и диаграммку

expression
| \
glvalue rvalue
| | \
lvalue xvalue prvalue

Возникают смутные сомнения, что скопипащено оно было с некоей грамматики. Отсюда и это странное смешение — rvalue и выражения. Хотя вот эти ветвления скорее обоснованы структурами синтаксического разбора,

O>>>>Объект — это уже физика языка, так вот живет объект как rvalue, выражением в данном случае будет именно std::vector<int>() -> arg, вот здесь оно и умрет, после инициализации параметра.

BFE>>>Выражение умрёт? Или умрёт объект?
O>> Давай так ) если считать, что мы принимаем связывание rvalue с простой ссылкой, то работает это правило
O>>
 (6.9) — A temporary object bound to a reference parameter in a function call (7.6.1.2) persists until the
O>>completion of the full-expression containing the call.

BFE>Зачем нужна эта сентенция, если утверждение процитированное выше —
Так она с дополнением )) "если считать, что мы принимаем связывание rvalue с простой ссылкой, то работает это правило ...". И именно так оно и должно звучать (имхо) в практических руководствах.
на этом компиляторе видно как работает в данном случае студийный компилятор. тут простой референс ведет себя как константный.
https://rextester.com/l/cpp_online_compiler_visual

#include <iostream>

static int count__ = 0;

struct class_type {
    class_type() {
       ++count__;
    }
    
    class_type(class_type const& ) { ++count__; }
    ~class_type() { --count__; }
    
    void foo(class_type const&, class_type, class_type&) {
         std::cout << "objects: " << count__ << std::endl;
    }
};

int main()
{
    {
        class_type& c0 = class_type();
        c0.foo(class_type(), class_type(), class_type());
        {
            class_type& c1=class_type();
            c1.foo(class_type(), class_type(), class_type());
        }
        c0.foo(class_type(), class_type(), class_type());
    }
    std::cout << "objects: " << count__ << std::endl;
}



O>>>> И если арг не проинициализируется от рвелью и не продлит жизнь объекту, он умрет.

BFE>>>Если арг не проинициализируется, то и функция вызвана не будет. Причём тут продление жизни для ссылок?
O>> так именно. "если проинициализируется и продлит жизнь". А то может ведь и не продлить (получим битую ссылку в теле)
BFE>Я не могу придумать конструкцию вызова функции без инициализации аргумента.

Но я не про инициализацию говорил, я говорил про потенциальную вероятность того, что ссылка окажется битая, т/к каким-то образом не произойдет материализация временного объекта (т/к там просто референс)