Как обмануть nodiscard?
В комментах к предыдущему посту Евгений правильно заметил, что аттрибут nodiscard можно заигнорировать. Правда непонятны кейсы, в которых это нужно делать и которые еще не притянутые были бы за уши. Думаю, что при корректном использовании атрибута, такой надобности не возникнет. Ну да ладно. Об этом мы поговорим попозже. Сейчас я перечислю некоторые способы обхода nodiscard, чисто из научного интереса. Предупреждаю сразу. Уберите маленьких детей от экрана и ни в коем случае не повторять дома. За последствия не отвечаю.
std::ignore. На этот вариант и ссылался Евгений. Суть в том, что этому безтиповому можно присвоить любое значение и не использовать его. Тогда и возвращаемое значение типа было использовано для преобразования в ignore, и мы потом этот ignore можем игнорировать. Подробнее тут. А для любителей покопаться в костях динозавров есть функция boost::ignore_unused.
Скастовать возвращаемое значение в void. Типа вот так: (void)someFunction(). Или более по-плюсовому co static_cast.
Присвоить возращаемое значение какому-то объекту. Но не использовать его.
Тогда появится варнинг, что переменная, которой мы присвоили возвращаемое значение, не используется нигде. А вот чтобы это обойти, нужно пометить эту переменную другим атрибутом [[maybe_unused]]. Например так: [[maybe_unused]] int i = foo ();
Сделать красивую шаблонную обертку над предыдущим пунктом, с variadic-templates и прочими радостями. И назвать ее discard.
Отличные новости для пользователей clang! Можно обернуть вызов функции в
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#endif
func_with_result();
#pragma clang diagnostic pop
#endif
Тогда и никаких варнингов генерироваться не будет. Для gcc есть что-то подобное, но там нельзя вроде все сразу отключить.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
func_with_result();
#pragma GCC diagnostic pop
На этом моя фантазия кончилась. Но получилось все равно солидно)
Повторю, что в большинстве случаев вы этим будете стрелять себе в лицо, и это скорее всего признак того, что вы что-то делаете не так или система спроектирована плохо.
Возможно вы знаете какие-нибудь еще способы? Обязательно делитесь ими в комментариях)
Stay dangerous. Stay cool.
#fun #cpp17 #compiler
В комментах к предыдущему посту Евгений правильно заметил, что аттрибут nodiscard можно заигнорировать. Правда непонятны кейсы, в которых это нужно делать и которые еще не притянутые были бы за уши. Думаю, что при корректном использовании атрибута, такой надобности не возникнет. Ну да ладно. Об этом мы поговорим попозже. Сейчас я перечислю некоторые способы обхода nodiscard, чисто из научного интереса. Предупреждаю сразу. Уберите маленьких детей от экрана и ни в коем случае не повторять дома. За последствия не отвечаю.
std::ignore. На этот вариант и ссылался Евгений. Суть в том, что этому безтиповому можно присвоить любое значение и не использовать его. Тогда и возвращаемое значение типа было использовано для преобразования в ignore, и мы потом этот ignore можем игнорировать. Подробнее тут. А для любителей покопаться в костях динозавров есть функция boost::ignore_unused.
Скастовать возвращаемое значение в void. Типа вот так: (void)someFunction(). Или более по-плюсовому co static_cast.
Присвоить возращаемое значение какому-то объекту. Но не использовать его.
Тогда появится варнинг, что переменная, которой мы присвоили возвращаемое значение, не используется нигде. А вот чтобы это обойти, нужно пометить эту переменную другим атрибутом [[maybe_unused]]. Например так: [[maybe_unused]] int i = foo ();
Сделать красивую шаблонную обертку над предыдущим пунктом, с variadic-templates и прочими радостями. И назвать ее discard.
Отличные новости для пользователей clang! Можно обернуть вызов функции в
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#endif
func_with_result();
#pragma clang diagnostic pop
#endif
Тогда и никаких варнингов генерироваться не будет. Для gcc есть что-то подобное, но там нельзя вроде все сразу отключить.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
func_with_result();
#pragma GCC diagnostic pop
На этом моя фантазия кончилась. Но получилось все равно солидно)
Повторю, что в большинстве случаев вы этим будете стрелять себе в лицо, и это скорее всего признак того, что вы что-то делаете не так или система спроектирована плохо.
Возможно вы знаете какие-нибудь еще способы? Обязательно делитесь ими в комментариях)
Stay dangerous. Stay cool.
#fun #cpp17 #compiler