(void)var实际上是什么意思?

24

请考虑以下main()函数:

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

使用cc -Wall -Wextra编译时,会生成警告信息“unused parameter”。

当我在函数中不需要使用参数时(例如在int参数没有被使用的信号处理函数中),我习惯采用以下方法:

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

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

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

我知道(void)是一个强制类型转换,所以我猜我正在强制转换变量。那么没有强制类型转换的var;行是做什么的?这是一个空赋值吗,还是一个空表达式?

我想要理解实际上发生了什么。


2
如果expr没有左值且不是函数调用,则expr;是一个没有效果的语句。它什么也不做。写(void) expr;可以抑制没有效果的语句的警告。在涉及到expr的无效语句中写入一个语句可以消除在函数参数列表中出现expr但未使用expr时的警告。 - Brandin
4个回答

23

这只是一种创建“无害”变量引用的方法。编译器不会因为未使用的变量而发出警告,因为您已经引用了值,并且它也不会因为你没有对表达式 var 的值做任何事情而发出警告,因为您明确将其转换为无效(nothing)表示您不关心该值。

我以前没有见过在变量上使用这种用法(因为我使用的编译器通常不会抱怨未使用的函数参数),但我经常看到它被用来指示编译器你并不真正关心一个函数的返回值。例如,printf()会返回一个值,但99%的C程序员不知道(或不关心)它返回什么。为了使一些蛮横的编译器或lint工具不对未使用的返回值发出警告,您可以将返回值强制转换为void,以表明您知道它存在,并且您明确不关心它。

除了向编译器传达您的意图(即您不关心此值)之外,它实际上并没有实际作用-它只是向编译器提供提示。


9
  (void)argc;
  (void)argv;

如果一个函数参数没有被使用,就像在你的程序中一样,那么这是通过某些编译器抑制未使用函数参数警告的惯用方式。任何好的编译器都不会生成这些语句的代码。
它评估了参数但对其不做任何操作,这对于大多数编译器来说不会发出警告。 (void) 强制转换用于使编译器不会产生另一个通知值未使用的警告。
另一种流行的抑制警告的方式是执行以下操作:
variable = variable;

注意,我知道一些编译器会在以下情况下发出另一个警告:
(void) arg;

类似于“无效语句”。


非常感谢!我不知道使用这种技术还可以引发其他错误(“语句无效”)。我们学校使用-Werror编译我们的项目,而我想要一个真实的成绩,哈哈! - Diti
1
就我所知,我的公司也使用-Werror进行编译:在大型项目刚开始使用时,启用它可能会带来一些痛苦,但如果你一开始就用它,情况也不会太糟。从长远来看,你打开并且保持更多的警告,你的代码将更好 - 不仅编译器能够帮助你找到真正的问题,而且程序员们被迫学习更多的语言知识,以避免某些警告,这有助于他们成为更好的程序员。 - JVMATL
@JVMATL “-Werror”的一个问题是在Makefile中,它通常会退出编译过程,而您可能希望通过转储所有警告来得到整体情况的概述。 - ouah
如果你使用'make -k'(-k ==“继续执行”),你仍然会收到所有(或大多数)警告。除非你正在使用递归Makefile… :)(http://aegis.sourceforge.net/auug97.pdf) - JVMATL
@JVMATL但是“继续前进”也会对其他(非编译)错误继续进行处理,这可能不是期望的行为。 - ouah

2

正如其他人正确指出的那样,它只是抑制了代码中未使用变量的编译器警告。 顺便说一句,Win32定义了UNREFERENCED_PARAMETER宏来实现这个目标。 我建议在你的代码中做类似的事情:

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

0

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


4
你能否提供数据或引用支持这个论点? - jcsahnwaldt Reinstate Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接