this->notes.
4.51K subscribers
56 photos
1 file
431 links
О разработке, архитектуре и C++.

Tags: #common, #cpp, #highload и другие можно найти поиском.
Задачки: #poll.
Мои публикации: #pub.
Автор и предложка: @vanyakhodor.
GitHub: dasfex.
Download Telegram
#cpp

Представьте вот такой код:

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 штук. В каждом варианты ответов по ощущениям. Если вам кажется, что у вас есть какая-то интересная опция, не указанная в опросах, смело пишите в комментарии.

Опросы буду держать где-то недельку. Потом их и пост удалю. И закину снапшот состояния аудитории (вас) на момент подведения итогов, чтобы вы тоже представляли, кто тут и как.
Сколько у вас коммерческого опыта (за деньги)?
Anonymous Poll
13%
<1 года
20%
1-3 года
24%
3-5 лет
21%
5-10 лет
17%
10-20 лет
5%
> 20 лет
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Спасибо большое!
🤝23🤓15💅4