Пометить некоторые функции и классы стандартной библиотеки атрибутом [[nodiscard]]

Andrey Davydov
Andrey Davydov

[[nodiscard]] классы:

  • thread
  • unique_lock
  • lock_guard
  • scoped_lock

[[nodiscard]] функции:

  • async

Эти списки, наверняка, могут быть расширены.

6
рейтинг
16 комментариев
yndx-antoshkka
+1

Можно пойти по пути наименьшего сопротивления, и завести library issue на это, благо подобная уже есть: cplusplus.github.io/LWG/lwg-active.html#2821

Хотите сами завести, или мне заняться?
yndx-antoshkka
Andrey Davydov
yndx-antoshkka, Я не смог найти где можно создай новый library issue, если вы подскажите, то я попробую сам это сделать.
Мне кажется, что мое предложение несколько осмысленнее, чем issue на которое вы сослались. std::launder, так же как и std::move, std::forward, методы size() и empty() у контейнеров, и так далее (наверное, любую constexpr функцию), стоило бы пометить [[pure]] а не [[discard]]. Вызывать их игнорируя результат бессмысленно но не "опасно", а вот проигнорированный std::thread приведет к std::terminate.
Andrey Davydov
yndx-antoshkka
Есть инструкция по созданию issue: isocpp.org/std/submit-issue Если возникнут вопросы - обращайтесь.

И да, ваше предложение намного более осмысленное :)
yndx-antoshkka
Andrey Davydov
yndx-antoshkka, я выполнил шаг 1 данной инструкции, создав тему на std-discussion groups.google.com/a/isocpp.org/forum/embed/?place=forum/std-discussion&showsearch=true&showpopout=true&parenturl=https://isocpp.org/forums/iso-c-standard-discussion#!topic/std-discussion/dE1ubDI3--c
Надеюсь дождаться какого-то полезного feedback'a оттуда.
Andrey Davydov
yndx-antoshkka
Andrey Davydov, обсуждение скатилось в лютую теорию. Предлагаю вам сделать следующее:
* завести issue на [[nodiscard]] std::async
* завести отдельный issue на [[nodiscard]] std::thread
* если есть желание - написать proposal на добавление [[nodiscard]] к *::empty(), make_shared(), make_unique()...
* если есть желание - продумать автоматическое помечание constexpr функций как [[nodiscard]] и тоже написать proposal

Постараюсь форсировать рассмотрение первых двух пунктов на ближайшем заседании. Пожалуйста, отпишитесь о заведенных issue и желании писать proposal в этом обсуждении.
yndx-antoshkka
Andrey Davydov
yndx-antoshkka, issue для std::async: cplusplus.github.io/LWG/lwg-active.html#2856
ответа на письмо про std::thread я пока жду, когда получу, отпишусь.
С proposal'ом на добавление [[nodiscard]] к функциям empty() и size() я не совсем согласен, мне кажется, что [[nodiscard]] неточный (недостаточный) термин для pure-функций. Что Вы думаете по поводу идеи добавить атрибут pure для функций, из которого, в частности, будет следовать, что они являются nodiscard? И именно наличие [[pure]], по-моему, должно следовать из constexpr. Правда, под именем "pure" он точно не будет стандартизирован, так как по смыслу он ближе не к GNU-му __attribute__((pure)), а к __attribute__((const)).
Proposal на добавление [[nodiscard]] к make_unique и make_shared, по-моему не очень логичный, так как с одной стороны игнорирование результата make_unique и make_shared не так опасно как std::async, а с другой так же бессмысленно, как и для математических функций sin, cos, .., fopen, malloc и еще тысячи других. Тогда надо либо помечать всю стандартную библиотеку, либо ничего.
Andrey Davydov
yndx-antoshkka
> issue для std::async: cplusplus.github.io/LWG/lwg-active.html#2856

Супер!

> Что Вы думаете по поводу идеи добавить атрибут pure для функций, из которого, в частности, будет следовать, что они являются nodiscard?

Я не специалист по написанию оптимизаторов, но мне кажется что проблема data-flow в clang полностью решена и такой атрибут не даст никакого преимущества при оптимизации. Я выясню поподробнее в WG21.

> И именно наличие [[pure]], по-моему, должно следовать из constexpr.

Всеми руками за! Если constexpr функция не имеет выходных параметров то применять [[nodiscard]] автоматически. На это понадобится proposal.

> Proposal на добавление [[nodiscard]] к make_unique и make_shared, по-моему не очень логичный, <...> так же бессмысленно, как и для математических функций sin, cos, .., fopen, malloc и еще тысячи других.

Математические функции скорее всего станут скоро constexpr, так что их помечать не придётся. make_unique/make_shared не попадают под pure функции, так как в них скрыт системный вызов. Помечать их, и множество других функций стандартной библиотеки, придётся вручную. Тут нужно выработать некий критерий, по которому определять, нужно ли помечать функцию как [[nodiscard]], пройтись по всей стандартной библиотеке отбирая функции с этим критерием, написать proposal.
yndx-antoshkka
Andrey Davydov
> Математические функции скорее всего станут скоро constexpr
А как проблему с errno решат?
Andrey Davydov
yndx-antoshkka
Запись в errno будет делать вызов функции не constant expression:
* если пользователь явно запросил constant expression ( constexpr float f = sqrt(-1.0f)) то будет ошибка компиляции
* если пользователь явно не требует constant expression (float f = sqrt(-1.0f)) то на рантайме выставится errno
Так сейчас уже реализовано в GCC и CLANG.

Это противоречит вашему предложению constexpr == [[pure]], но всё ещё хорошо ложится на предложение "Если constexpr функция не имеет выходных параметров то применять [[nodiscard]] автоматически"
yndx-antoshkka
Andrey Davydov
yndx-antoshkka, Понятно, спасибо за объяснение. По поводу std::thread я получил такой ответ:
2017-01-24 16:20 GMT+01:00 Andrey Davydov <andrey.a.davydov@gmail.com>:
> Section 30.3.2 [thread.thread.class]
> Discussion:
> Because destructor of the std::thread can call std::terminate (section
> 30.3.2.3), result of any function returning std::thread must not be
> discarded.

Hi Andrey, since this is a very general, broad statement, I find it
hard to add an issue for this. My recommendation is to write a short
proposal that explains the full impact change of this suggestion on
the current working draft and with Audience targeting Library Working
Group. If you have any questions in regard to writing up a proposal,
please contact me via the lwgchair address (It is really not so hard),
but here are some short examples:

open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0340r0.html
open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0014r0.pdf

Note: The next mailing deadline is February 6th, 14:00 UTC. You need
to allocate a document number from via by providing the following
three information pieces:

1) Title
2) Audience list
3) Author list

Thanks,

- Daniel

Так что, с std::thread не удастся ограничиться issue и надо делать proposal.
Andrey Davydov
yndx-antoshkka
При возникновении любых вопросов - обращайтесь, помогу. Если понадобится помощь с английским или с тем как начать писать proposal - обращайтесь.
yndx-antoshkka
Andrey Davydov
yndx-antoshkka, Спасибо!
Я, наверное, только не в ближайшее время этим займусь.
Andrey Davydov
yndx-antoshkka
Proposal на эту тему: open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0600r0.pdf

В нём нехватает [[nodiscard]] для std::thread. Если хочется по быстрому добавить ещё куда-то nodiscard - скажите, на заседании озвучу.
yndx-antoshkka
Andrey Davydov
yndx-antoshkka,
Наверное, реально по-быстрому добавить nodiscard к *::empty(), об этом еще Sutter писал год назад: herbsutter.com/2016/03/11/trip-report-winter-iso-c-standards-meeting
Andrey Davydov
yndx-antoshkka
p0600r0 обсудили, но официально в С++17 принять не успели. Тему с std::thread не затрагивали на обсуждении.

Однако большинство имплементаций в скором времени внедрят эту бумагу, даже не смотря на то, что она не является ещё частью стандарта. Боле того, имплементации имеют право добавлять [[nodiscard]] по своему усмотрению.

Итого: В скором времени в черновик будущего С++20 включат p0600r0, имплеменетации начнут экспериментировать и добавлять [[nodiscard]]. Позже (через годик) можно уже будет написать бумагу, помечающую методы как [[nodiscard]], исходя из "лучших практик" (например "2 из 3 стандартных библиотек пометили этот метод как [[nodiscard]], пользователям это нравится, давайте обяжем имплементации помчать этот метод").

А то тех пор - приглядываемся к кандидатам на [[nodiscard]], экспериментируем на своих классах...
yndx-antoshkka
yndx-antoshkka
Добавили для async(), malloc(), allocate(), operator new в С++20

Авторы начали работать над следующим предложением, по добавлению [[nodiscard]] к функциям.

Попробуйте изложить свои мысли по добавлению nodiscard к классам в виде proposal. Вот мини инструкция по написанию: stdcpp.ru/podgotovka-predlozheniya-v-standart-c-instruktsiya
yndx-antoshkka
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).