(void)var实际上做了什么?

考虑以下main()

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

在使用cc -Wall -Wextra编译时,会生成警告“未使用的参数”。

当我不需要在函数中使用参数时(例如在不使用其int参数的信号处理函数中),我习惯于执行以下操作:

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

(对于那个特定的main() ,我有时会看到其他人这样做: argv = argv - argc + argc

但是(void)var实际上做了什么?

我知道(void)是一个演员,所以我想我正在抛弃变量? 变量是什么var; 线(没有演员)呢? 这是一个空任务,一个空表达式?

我想了解究竟发生了什么。

它只是一种创建对变量的“无害”引用的方法。 编译器不会抱怨未使用的变量,因为你确实引用了这个值,并且它没有抱怨你没有对表达式var的值做任何事情,因为你明确地将它转换为void(无),表明你不关心价值。

我之前没有在变量上看到过这种用法(因为我使用的编译器通常不会抱怨未使用的函数参数,但是我看到这经常用于向编译器表明你并不真正关心的返回值一个function。 例如, printf(),返回一个值,但99%的C程序员不知道(或关心)它返回的内容。 为了使一些繁琐的编译器或lint工具不抱怨未使用的返回值,您可以将返回值转换为void,以表明您知道它在那里,并且您明确地不关心它。

除了将您的意图(您不关心此值)传达给编译器之外,它实际上并没有任何事情 – 它只是对编译器的一个提示。

  (void)argc; (void)argv; 

如果没有使用函数参数,就像你的程序一样,那么这是抑制某些编译器发出的未使用函数参数警告的惯用方法。 任何体面的编译器都不会使用这些语句生成代码。

它会对参数进行评估,但对其没有任何作用,这对大多数编译器都不会发出警告。 使用(void)强制转换,因此编译器不会产生另一个警告,通知该值未被使用。

压制警告的另一种流行方法是:

 variable = variable; 

请注意,我知道一些编译器将在以下情况下发出另一个警告:

 (void) arg; 

喜欢“没有效果的陈述”。

正如其他人正确指出的那样,它只是禁止编译器警告代码中未使用的变量。 顺便说一下,Win32定义了UNREFERENCED_PARAMETER宏来达到这个目标。 我的建议是在你的代码中做出类似的东西:

 #ifdef _WIN32 # define UNUSED(x) UNREFERENCED_PARAMETER(x) #else # define UNUSED(x) (void) x #endif 

这可能会提高代码效率,因为函数调用不需要加载参数的寄存器。