#cpp
Представьте вот такой код:
Где
Как вы будете писать код в (1)?
Вы наверное проверите какие-то свойства вашего
Или можете вообще сравнить его с чем-то (вдруг там всё-таки какое-то конкретное значение появилось):
Делаете ли вы что-то неправильное? Должен ли компилятор вам подсказать проблему в таком коде? Может UBsan? Может clang-tidy?
Да нет.
Более того, даже если вы сделаете что-то такое:
Вы возможно ничего плохого не сделали. Вы просто не знаете, что точно там лежит.
Конечно, проблемы могут возникнуть, если вы, не проверив состояние вашего объекта, будете предполагать, что он обладает какими-то свойствами. Например, думать, что он не пустой. Или что он содержит сколько-то каких-то элементов. Это всё может быть, но вообще-то мы точно утверждать не можем.
Использовать объект после
Вы опять же про этот
Чем эти примеры отличаются от работы с переменной после
Да ничем.
Мы так яро привыкли к правилу «использовать переменную после
Хотя никакого UB тут нет. UB может возникнуть от того, что вы пользуетесь объектом, предполагая, что у него есть какие-то свойства. Точно так же и в нашей функции
И к сожалению эта ошибка стала достаточно частой, чтобы мы выработали ощущение неправильности происходящего. Само действие стало табу. В clang-tidy вон проверка отдельная есть (которую приходится игнорировать с
Отсюда рождаются ментальные модели вида
• «после std::move ничего нельзя»
• «после std::move можно только переприсваивать или уничтожать объект, всё остальное запрещено».
Это упрощения, которые мы себе придумали, чтобы меньше думать. И они почти всегда работают. Но иногда всё же нет.
Давайте думать и не вестись на вот эти попытки наших развитых эволюционировавших мозгов упрощать. Это мы профессионально ленимся.
P.S. Важно подчеркнуть ещё один факт.
Состояние объекта после
А для стандартной библиотеки довольно просто понять, можно ли вызывать метод у мувнутого объекта: у метода не должно быть precondition. Например у
@thisnotes. Patreon, newsletter.
Спасибо Artyom Garkavy и niki4smirn.
Представьте вот такой код:
auto object = GetObject(params...);
auto another = object;
MessAround(object);
// (1) you want to write some logic here
Где
MessAround — функция, которая непредсказуемым образом меняет значение вашего object. То есть значение соответствует всем инвариантам, но вы не знаете, какое конкретно. Как вы будете писать код в (1)?
Вы наверное проверите какие-то свойства вашего
object. Может он там empty()/isNull()/valid(). Или может вы сразу решите его почистить: clear(). Или может присвоить что-нибудь туда захотите: object = Object{1, 2, 3}.Или можете вообще сравнить его с чем-то (вдруг там всё-таки какое-то конкретное значение появилось):
if (object == "str_val"_obj) {...}
Делаете ли вы что-то неправильное? Должен ли компилятор вам подсказать проблему в таком коде? Может UBsan? Может clang-tidy?
Да нет.
Более того, даже если вы сделаете что-то такое:
auto first = object["first"];
Вы возможно ничего плохого не сделали. Вы просто не знаете, что точно там лежит.
MessAround туда могло подложить что угодно. Конечно, проблемы могут возникнуть, если вы, не проверив состояние вашего объекта, будете предполагать, что он обладает какими-то свойствами. Например, думать, что он не пустой. Или что он содержит сколько-то каких-то элементов. Это всё может быть, но вообще-то мы точно утверждать не можем.
Использовать объект после
MessAround это примерно то же самое, что написать функцию, решающую некоторую задачу в вакууме. На примере функции, решающей любую задачу:
void solve(Object obj) {...}
Вы опять же про этот
obj ничего не знаете. Вам надо проверить разные корнер кейсы. А потом как-то там решать вашу проблему. Чем эти примеры отличаются от работы с переменной после
std::move? Да ничем.
Мы так яро привыкли к правилу «использовать переменную после
std::move опасно», что в нашей ментальной модели это часто равносильно undefined behaviour. Уже само это действие вызывает подозрения. Code smell так называемый. Хотя никакого UB тут нет. UB может возникнуть от того, что вы пользуетесь объектом, предполагая, что у него есть какие-то свойства. Точно так же и в нашей функции
solve, которая может не учесть какие-то потенциальные входные данные. Пытаться разыменовать пустой указатель, не проверив его, неправильно. И к сожалению эта ошибка стала достаточно частой, чтобы мы выработали ощущение неправильности происходящего. Само действие стало табу. В clang-tidy вон проверка отдельная есть (которую приходится игнорировать с
NOLINT). Отсюда рождаются ментальные модели вида
• «после std::move ничего нельзя»
• «после std::move можно только переприсваивать или уничтожать объект, всё остальное запрещено».
Это упрощения, которые мы себе придумали, чтобы меньше думать. И они почти всегда работают. Но иногда всё же нет.
Давайте думать и не вестись на вот эти попытки наших развитых эволюционировавших мозгов упрощать. Это мы профессионально ленимся.
P.S. Важно подчеркнуть ещё один факт.
Состояние объекта после
std::move — всем известное «valid but unspecified». По стандарту это работает для стандартной библиотеки. Но кажется, мы уже настолько к этому привыкли, что считаем это данностью в любом случае. Не то чтобы это ожидание обосновано. Авторы библиотек делают что хотят. Но наверное писать ломающий это ожидание код всё-таки не надо. А для стандартной библиотеки довольно просто понять, можно ли вызывать метод у мувнутого объекта: у метода не должно быть precondition. Например у
std::vector::front он есть: !empty(); у std::vector::clear такого нет. @thisnotes. Patreon, newsletter.
Спасибо Artyom Garkavy и niki4smirn.
👍14👎2
Сейчас не я вам расскажу что-нибудь, а вы мне.
Расскажете мне про себя.
Я в целом никогда конкретно не пытался выяснить, кто моя аудитория. Были опросы вида "что вам интересно", где обычно надо формочку заполнить. А такое делает абсолютное меньшинство.
Хочу знать про вас чуть больше. Может мне это поможет куда-то смещать вектор.
Надеюсь, тыкнуть в опросы вам будет достаточно ненапряжно. Их 11 штук. В каждом варианты ответов по ощущениям. Если вам кажется, что у вас есть какая-то интересная опция, не указанная в опросах, смело пишите в комментарии.
Опросы буду держать где-то недельку. Потом их и пост удалю. И закину снапшот состояния аудитории (вас) на момент подведения итогов, чтобы вы тоже представляли, кто тут и как.
Расскажете мне про себя.
Я в целом никогда конкретно не пытался выяснить, кто моя аудитория. Были опросы вида "что вам интересно", где обычно надо формочку заполнить. А такое делает абсолютное меньшинство.
Хочу знать про вас чуть больше. Может мне это поможет куда-то смещать вектор.
Надеюсь, тыкнуть в опросы вам будет достаточно ненапряжно. Их 11 штук. В каждом варианты ответов по ощущениям. Если вам кажется, что у вас есть какая-то интересная опция, не указанная в опросах, смело пишите в комментарии.
Опросы буду держать где-то недельку. Потом их и пост удалю. И закину снапшот состояния аудитории (вас) на момент подведения итогов, чтобы вы тоже представляли, кто тут и как.
Где вы живёте?
Anonymous Poll
11%
Беларусь
62%
Россия
4%
Сербия
3%
Польша
3%
Великобритания
9%
Другая Европа
8%
Где-то ещё
Сколько у вас коммерческого опыта (за деньги)?
Anonymous Poll
13%
<1 года
20%
1-3 года
24%
3-5 лет
21%
5-10 лет
17%
10-20 лет
5%
> 20 лет
Ваш текущий уровень/грейд в текущей компании?
Anonymous Poll
7%
Не работаю
8%
Student/intern
9%
Junior
31%
Middle
30%
Senior
7%
Stuff/Principal/любой IC выше senior
5%
Руководитель (работяг)
1%
Руководитель (руководителей)
0%
cXo
2%
Другое
Какой размер вашей компании?
Anonymous Poll
11%
1-50
15%
50-200
13%
200-1k
6%
1k-2k
7%
2k-5k
9%
5k-10k
5%
10k-20k
21%
20k+
1%
Работаю на себя/freelance
12%
Не работаю
Чем в основном занимаешься?
Anonymous Poll
50%
Бэкенд
8%
Инфраструктура / SRE
6%
Трейдинг/ hft / other low latency
5%
Game development
6%
ML
8%
Embedded
0%
Mobile
1%
Front
16%
Другое
Личные интересы вне языков программирования (mulitple):
Anonymous Poll
43%
C++
26%
Другие языки программирования
42%
Backend архитектура
29%
Databases / other storage
58%
Low-level performance
36%
Backend performance
55%
Concurrency
22%
Engineering management
24%
Другое
😁2
Что ты сейчас пытаешься улучшить в своей карьере?
Anonymous Poll
8%
Найти первую работу
22%
Дорасти до Senior
14%
Вырасти из Senior выше (Staff / Principal)
4%
Вырасти в лида
3%
Вырасти в лида лидов
8%
Уйти в бигтех откуда-то поменьше
13%
Уйти в tech-heavy домен (БД/HFT/другое)
7%
Запустить стартапчик, чтобы потом его продать
21%
Ничего. У меня всё и так круто