Зачем приводить неиспользуемые возвращаемые значения к void?

StackOverflow https://stackoverflow.com/questions/689677

  •  22-08-2019
  •  | 
  •  

Вопрос

int fn();

void whatever()
{
    (void) fn();
}

Есть ли какая-либо причина приводить неиспользуемое возвращаемое значение к void, или я прав, считая, что это пустая трата времени?

Следовать за:

Что ж, это кажется довольно всеобъемлющим.Я полагаю, что это лучше, чем комментировать неиспользуемое возвращаемое значение, поскольку самодокументируемый код лучше комментариев.Лично я отключу эти предупреждения, так как это лишний шум.

Я съем свои слова, если из-за этого сбежит ошибка...

Это было полезно?

Решение

Дэвида отвечать в значительной степени покрывает мотивацию этого, чтобы явно показать другим «разработчикам», что вы знаете, что эта функция возвращает, но вы явно ее игнорируете.

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

Я думаю, что для C++ это, пожалуй, единственное место, где я предпочитаю использовать приведения в стиле C, поскольку использование полной статической нотации приведения здесь кажется излишним.Наконец, если вы просматриваете или пишете стандарт кодирования, то также хорошей идеей будет явно указать, что вызовы перегруженных операторов (без использования нотации вызова функций) также должны быть освобождены от этого:

class A {};
A operator+(A const &, A const &);

int main () {
  A a;
  a + a;                 // Not a problem
  (void)operator+(a,a);  // Using function call notation - so add the cast.

Другие советы

На работе мы используем это, чтобы подтвердить, что функция имеет возвращаемое значение, но разработчик утверждает, что его можно игнорировать.Поскольку вы пометили вопрос как C++, вам следует использовать static_cast:

static_cast<void>(fn());

Что касается компилятора, приведение возвращаемого значения к void не имеет особого смысла.

Истинная причина этого восходит к инструменту, используемому в коде C, под названием ворс.

Он анализирует код в поисках возможных проблем и выдает предупреждения и предложения.Если функция вернула значение, которое затем не было проверено, lint предупредил бы, если бы это было случайно.Чтобы замолчать lint при этом предупреждении вы вызываете (void).

Кастинг в void используется для подавления предупреждений компилятора о неиспользуемых переменных и несохраненных возвращаемых значениях или выражениях.

В стандарте (2003) в §5.2.9/4 говорится:

Любое выражение может быть явно преобразовано в тип «cv void». Значение выражения выброшенный.

Итак, вы можете написать:

//suppressing unused variable warnings
static_cast<void>(unusedVar);
static_cast<const void>(unusedVar);
static_cast<volatile void>(unusedVar);

//suppressing return value warnings
static_cast<void>(fn());
static_cast<const void>(fn());
static_cast<volatile void>(fn());

//suppressing unsaved expressions
static_cast<void>(a + b * 10);
static_cast<const void>( x &&y || z);
static_cast<volatile void>( m | n + fn());

Все формы действительны.Обычно я делаю это короче:

//suppressing  expressions
(void)(unusedVar);
(void)(fn());
(void)(x &&y || z);

Это тоже нормально.

Для функциональности вашей программы приведение к void не имеет смысла.Я бы также сказал, что вам не следует использовать его, чтобы сигнализировать о чем-то человеку, читающему код, как предложено в ответе Дэвида.Если вы хотите сообщить что-то о своих намерениях, лучше использовать комментарий.Добавление такого приведения будет только выглядеть странно и вызовет вопросы о возможной причине.Просто мое мнение...

Я знаю, что это старая тема, но язык развивается, и для полноты картины следует упомянуть, что начиная с C++17 у нас есть [[maybe_unused]] атрибут, который можно использовать вместо атрибута void бросать.

Бросок в пустоту бесплатен.Это всего лишь информация для компилятора, как с этим обращаться.

В C совершенно нормально приводить к void.Практически любой поймет смысл этого заявления.

В C++ в вашем распоряжении есть другие инструменты.Поскольку приведения C обычно не одобряются, а явное приведение к void, скорее всего, удивит ваших коллег (а меня это удивляет), у меня где-то есть этот шаблон функции

template <typename T>
void use_expression(const T&) {}

и я использую

...
use_expression(foo());

где бы я написал (void)foo() в С.

Кроме того, при проверке соответствия вашего кода стандартам MISTA (или другим) автоматические инструменты, такие как LDRA, не позволят вам вызывать функцию, имеющую тип возвращаемого значения, без возврата значения, если только вы явно не приведете возвращаемое значение к (void).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top