(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
这可能会提高代码效率,因为函数调用不需要加载参数的寄存器。