Подтвердить что ты не робот

Использование (void) перед вызовом функции

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

Какова цель (void) перед вызовом функции, например

(void)func1();

Я предполагаю, что это то же самое, что просто вызвать func1();

Поэтому вызов (void) просто позволяет другим программистам знать, что тип возвращаемого значения будет проигнорирован, например, если func1() имел тип возврата int, или компилятор может выполнить некоторые оптимизации для функции? Возможно, в этом есть еще одна причина - это даже законный С++ или, возможно, это остатки C, видимые в каком-то унаследованном коде.

Спасибо

4b9b3361

Ответ 1

Приведение в void может иметь семантический эффект в одном случае: где значение является операндом оператора запятой и переопределяет оператор запятой, литой в void будет подавлять его:

struct S {
  int operator,(int) { return 0; }
};
std::cout << (S(), 42) << '\n';           // prints '0'
std::cout << ((void) S(), 42) << '\n';    // prints '42'

Ответ 2

Он предотвращает предупреждение, если какая-либо функция объявлена ​​с атрибутом: "Предупреждать, если возвращаемое значение не используется/не проверено"

Возможно, дубликат Предупреждение: игнорирование возвращаемого значения 'scanf', объявленного с атрибутом warn_unused_result

Подробнее о документации gcc: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html (warn_unused_result)

Ответ 3

Это очень мало. Он явно превращает линию в выражение void, то есть выражение, которое используется только для его побочных эффектов и значение которого отбрасывается. Таким образом, строки

func1();

и

(void)func1();

сделает то же самое. Может быть какая-то оптимизация, которая может быть выполнена, если компилятор знает, что значение выражения не используется, но вполне вероятно, что компилятор может понять это с явным (void) или без него.

Он может использоваться как форма документации, где программист пытается сделать очевидным, что они не используют значение выражения.

Ответ 4

Еще одно странное использование заключается в том, чтобы позволить функции неизвестного типа возврата использоваться рядом с оператором , в качестве оператора последовательности. То есть, decltype( f(), g() ), где вы хотите сказать, что "f может работать с (), как может g, и я хочу, чтобы этот тип был типом, который g() возвращает". Однако, если f() возвращает такой тип, что operator, перегружен, результат будет неожиданным.

Итак, вы делаете decltype( void(f()), g() ) и отбрасываете возвращаемое значение f() перед вызовом operator,, поэтому вам гарантированно получить встроенный оператор последовательности вместо неизвестного типа переопределения.