Constantine
О! Антон. Вам наверняка будет интересно. Нашел очень странный фич оптимизатора вижака
Constantine
https://godbolt.org/g/HUqhpq
🐙 Antony
а почему просто не написать: operator string_view() const noexcept & ;
тогда сломается void foo(string_view sw); foo(string{"Hello word!"}); // OK, right now
Constantine
https://godbolt.org/g/HUqhpq
В этом примере можно заметить, что функция f1 будет сгенерирована безумно плохо при компиляции с /EHsc
Aidar
ох не нравятся мне костыли в языке
Constantine
В этом примере можно заметить, что функция f1 будет сгенерирована безумно плохо при компиляции с /EHsc
Все это исправляется явным указанием конструктора const_iterator https://godbolt.org/g/UAxF1B
Constantine
Мораль: чтобы вижак нормально работал, нужно, видимо, не использовать struct-init
🐙 Antony
Если у вас есть учётка, попробуйте отправить им багу.
Constantine
Я им отправлю, только проблемы с оптимизацией под /EHsc судя по всему очень давние и какие-то by design
Constantine
при этом /EHsc является основной практической настройкой
Constantine
в данном примере такое ощущение, будто компилятор опасается выброшенного исключения при {} - инициализации структуры с size_t
Aidar
а математически можно заставить компиль распозновать удлинение времени жизни в сложных случаях?
🐙 Antony
а математически можно заставить компиль распозновать удлинение времени жизни в сложных случаях?
Да, там Саттер прорабатывает более общее решение, но оно весьма противоречивое
Aidar
на объекты бы повесить те же штуки что и на функции
Constantine
в общем, категорически рекомендую добавлять /EHsc при проверке тех или иных решений для msvc
Constantine
потому что может приводить к полному сбою всей оптимизации
Aidar
хотяб для инициализации
а хотя не уг какоето
Aidar
слишком жирно
🐙 Antony
на объекты бы повесить те же штуки что и на функции
Тогда можно получить javascript с вечной проблемой утекающей в непонятном месте памяти
Berkus
да ну его
го писать на го - тупо же звучит, поэтому и не пишет :D
🦥Alex Fails
ага, да и к тому же я ж уже так шутил)
🐙 Antony
а почему надо держаться за этот кейс?
это популярный и нормальный кейс В Boost его попробовали убрать, и поломался весь пользовательский код
Anatoly
интересно, какой смысл вкладывался. даже если предположить, что сигнатура была до появления std::string_view просто std::string.
🐙 Antony
а почему надо держаться за этот кейс?
В более вменяемом виде он выглядит как void foo(string_view sw); string bar(); foo(bar()); // OK, right now
Anatoly
ok
Constantine
нужно просто нормально написать для всяких std::vector::operator [] ref-quailifier
Aidar
ну вон там стрингвью
Anatoly
@antoshkka так, а прострел ноги в том, что ...? ну, передали в std::string_view временный объект, который будет жить до конца полного выражения. ну передали в функцию. функция же не дура сохранить где-то std::string_view и использовать после.
Constantine
в string_view нужно запретить вообще временные объекты передавать)
Aidar
просто какбы у stringview семантика ссылки неявная
Aidar
и вроде хранить можно изза этого
Constantine
я бы сказал, что в C++ есть чудесная проблема преобразования && в const&
Aidar
даже 2 или 3
Constantine
а почему просто не написать: operator string_view() const noexcept & ;
потому что && можно в const& преобразовать
Constantine
const& сигнатура аналогична const
Constantine
operator string_view() noexcept & должно быть
Constantine
string_view это принципиально & тип, насколько я понимаю, он не может захватить владение
🐙 Antony
operator string_view() noexcept & должно быть
Это всё равно не 100% гарантия string_view sw; { string s{"hello word. hello word. hello word. hello word. hello word. "}; sw = s; } std::cout << sw; // Oops!
Constantine
Это всё равно не 100% гарантия string_view sw; { string s{"hello word. hello word. hello word. hello word. hello word. "}; sw = s; } std::cout << sw; // Oops!
По моему текущего мнению все хорошо, если считать 1. Объект & живет минимум scope выше чем оператор, и только с него можно снимать view 2. Объект && живет оператор
Constantine
Т.е. если я создаю или присваиваю view-объект с нарушением правил жизни, я сам буратино
Constantine
Хотя я предпочел бы иметь view-объекты немутабельными
Constantine
Как &
Berkus
Enter Rust
Constantine
По моему текущего мнению все хорошо, если считать 1. Объект & живет минимум scope выше чем оператор, и только с него можно снимать view 2. Объект && живет оператор
Вроде как в этих правилах все хорошо, если view объект создается из объекта &, потому что переданный объект гарантированно живет в scope, в котором объявлен view-объект
Aidar
ну там не нужна гарантия
Aidar
давайте оставим как есть
Constantine
Ну кроме того, что && конвертируемо языком в const& и это все ломает
Constantine
я поэтому и сказал что это костыль
ну указатель без владения ты никогда не пофиксишь, а это пример с семантикой указателя без владения
Aidar
ну раст +- говорят чекает хотя я не проверял
Aidar
на явных штуках наверное
Constantine
да раст небось заставит тебя доказывать что объект не сдохнет
Berkus
удобно вот так хейтить то сразу, да?
Constantine
удобно вот так хейтить то сразу, да?
речь же про пример когда это утверждение неверно)
Constantine
я предполагаю ошибку вроде "I'm not sure this reference is not dead, gimme the prove"
Berkus
я предполагаю ошибку вроде "I'm not sure this reference is not dead, gimme the prove"
где ты ее предполагаешь, и почему ты считаешь что бороу чекер не справится? ты изучал как он работает или хотя бы прочитал немного матсакиса?
Berkus
ну в расте если функция консьюмит этот стринг вью, то bar(foo()) валиден - bar заберет ownership себе и спокойно внутри себя похоронит
Berkus
если не консьюмит то тоже должно быть нормально, не могу сказать точно почему я так думаю сейчас правда
Berkus
а, ну собсно borrow будет на время вызова, а потом дропнется
Constantine
ну в расте если функция консьюмит этот стринг вью, то bar(foo()) валиден - bar заберет ownership себе и спокойно внутри себя похоронит
а как это реализовано? тут же с точки зрения плюсов шаблонная функция bar() должна быть, либо она должна значение получать
Berkus
если ты передаешь значение то оно консьюмится
Berkus
let a = "foo"; g(&a); // g сжирает &a f(a); // f сжирает а h(a); // хуюшки
Berkus
примерно так
Constantine
let a = "foo"; g(&a); // g сжирает &a f(a); // f сжирает а h(a); // хуюшки
ну это по сути плюсовая модель с точность до проверки, что после std::move() нельзя объект использовать
Constantine
т.е. g() по сигнатуре получает & и обязана не делать side effect f(), h() по сигнатуре получает значение и его перемещают правильно?
Berkus
близко, но не совсем, в с++ нету lifetime annotations
🦥Alex Fails
{}
Constantine
(под side effect подразумеваю что функция не имеет права присваивать ссылку кому-либо, кроме локальных переменных и возвращаемого view-значения)
Constantine
близко, но не совсем, в с++ нету lifetime annotations
у меня сейчас конвенция на это есть)))
Berkus
в конвенции нет бороу чекера, так что это баловство в целом
Constantine
компиль-тайм чекера нет, да