2014-01-10 3 views
7

Рассмотрим следующий main():Что делает (void) var на самом деле?

int main(int argc, char *argv[]) 
{ 
    return (0); 
} 

При компиляции с cc -Wall -Wextra, предупреждения говоря "не используется параметр" получить сгенерированные.

Когда мне не нужно использовать параметр в функции (например, в signal handler function, что не использует его параметра int), я привык делать следующее:

int main(int argc, char *argv[]) 
    { 
     (void)argc; 
     (void)argv; 
     return (0); 
    } 

(для этого конкретного main(), я иногда вижу другие люди: argv = argv - argc + argc)

Но , что делает (void)var фактически do?

Я понимаю, что (void) - это отливка, поэтому, я думаю, я отбрасываю переменную? Что делает линия var; (без актеров)? Это пустое задание, пустое выражение?

Я хотел бы понять, что на самом деле происходит.

+2

Если выражение не имеет Левое и не вызов функции, то 'выражение;' это заявление без эффекта. Он ничего не делает. Написание '(void) expr;' отменяет предупреждение оператора без эффекта. Написание инструкции без эффекта, включающей выражение expr', замалчивает предупреждения, связанные с использованием 'expr' в функции, в которой в списке параметров появляется выражение' expr'. – Brandin

ответ

13

Это всего лишь способ создания «безобидной» ссылки на переменную. Компилятор не жалуется на неиспользуемую переменную, потому что вы ссылались на это значение, и он не жалуется, что вы ничего не делали со значением выражения var, потому что вы явно передали его в пустоту (ничего), указывая что вы не заботитесь о ценности.

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

Другое, чем сообщить свое намерение (что вам не важно это значение) компилятору, на самом деле это не do ничего - это всего лишь намек на компилятор.

4
(void)argc; 
    (void)argv; 

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

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

Другой популярный способ подавить предупреждение это сделать:

variable = variable; 

Обратите внимание, что я знаю, некоторые компиляторы, которые будут выдавать еще одно предупреждение в наличии:

(void) arg; 

как «заявление без эффекта ».

+0

Большое спасибо! Я не знал, что другие ошибки («заявление без эффекта») могут быть подняты с помощью этой техники. Моя школа компилирует наши проекты с помощью '-Werror', и я хочу получить оценку, ха-ха! – Diti

+1

Для того, что это стоит, моя компания тоже компилируется с помощью -Werror: это больно, когда вы впервые включаете ее для большого проекта, но не так уж плохо, если вы начнете с нее, и в конечном итоге, больше предупреждений, которые вы поворачиваете и лучше, чем лучше, ваш компилятор найдет для вас реальные проблемы, но программисты вынуждены больше узнать об этом языке, поскольку они работают над тем, как избежать определенных предупреждений, и это помогает им лучше кодировщикам в долгое время. – JVMATL

+0

@JVMATL Одна из проблем с '-Werror' находится в Makefile, она обычно выходит из процесса компиляции, в то время как вам может быть интересно иметь общую картину с дампом всех предупреждений. – ouah

1

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

+0

Можете ли вы поддержать это утверждение некоторыми данными или ссылкой? –

1

Как правильно отметили другие лица, он просто подавляет предупреждение компилятора о неиспользуемой переменной в вашем коде. Btw, Win32 для достижения этой цели определяет UNREFERENCED_PARAMETER макрос. Мое предложение сделать что-то подобное в вашем коде:

#ifdef _WIN32 
# define UNUSED(x) UNREFERENCED_PARAMETER(x) 
#else 
# define UNUSED(x) (void) x 
#endif 
Смежные вопросы