Зачем отбрасывать неиспользуемые возвращаемые значения в void? - PullRequest
104 голосов
/ 27 марта 2009
int fn();

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

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

Продолжение:

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

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

Ответы [ 9 ]

71 голосов
/ 27 марта 2009

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

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

Я думаю, что для 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.
43 голосов
/ 27 марта 2009

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

static_cast<void>(fn());

Пока компилятор преобразует возвращаемое значение в void, значение не имеет.

35 голосов
/ 27 марта 2009

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

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

22 голосов
/ 23 августа 2011

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

Стандарт (2003) гласит в п. 5.2.9 / 4:

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

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

//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);

Это тоже хорошо.

4 голосов
/ 23 декабря 2018

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

4 голосов
/ 27 марта 2009

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

3 голосов
/ 24 августа 2011

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

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

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

а я пользуюсь

...
use_expression(foo());

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

3 голосов
/ 27 марта 2009

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

1 голос
/ 20 марта 2015

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

...