我如何最好地沉默关于未使用的variables的警告?

我有一个跨平台的应用程序,在我的一些function并不是所有传递给函数的值都被使用。 因此,我从GCC得到一个警告,告诉我有没有使用的variables。

这个警告的最佳编码方式是什么?

函数的#ifdef?

#ifdef _MSC_VER void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal qrLeft, qreal qrTop, qreal qrWidth, qreal qrHeight) #else void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal /*qrLeft*/, qreal /*qrTop*/, qreal /*qrWidth*/, qreal /*qrHeight*/) #endif { 

这是如此丑陋,但似乎是编译器喜欢的方式。

或者,我将零分配给函数结尾处的variables? (这是我讨厌的,因为它正在改变程序stream程中的某些东西来使编译器警告无声)。

有没有正确的方法?

你可以把它放在“ (void)var; ”expression式 (什么也不做),以便编译器看到它被使用。 这在编译器之间是可移植的。

例如

 void foo(int param1, int param2) { (void)param2; bar(param1); } 

要么,

 #define UNUSED(expr) do { (void)(expr); } while (0) ... void foo(int param1, int param2) { UNUSED(param2); bar(param1); } 

在gcc中,你可以使用__attribute__((unused))预处理指令来实现你的目标。 例:

 int foo (__attribute__((unused)) int bar) { return 0; } 

你目前的解决scheme是最好的 – 如果你不使用它的话,注释掉参数名称。 这适用于所有的编译器,所以你不必使用预处理器来专门为GCC做。

一位同事在这里指出我这个漂亮的小macros

为了方便起见,我将包含下面的macros。

 #ifdef UNUSED #elif defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) #elif defined(__LCLINT__) # define UNUSED(x) /*@unused@*/ x #else # define UNUSED(x) x #endif void dcc_mon_siginfo_handler(int UNUSED(whatsig)) 

更简洁的方法是只注释variables名称:

 int main(int /* argc */, char const** /* argv */) { return 0; } 

对不起,这样一个迟到的答案。

gcc默认不标记这些警告。 这个警告必须已经通过向编译器传递-Wunused-parameter明确地打开,或者通过传递-Wall -Wextra (或可能的一些其他标志组合)隐式地-Wall -Wextra

未使用的参数警告可以简单地通过向编译器传递-Wno-unused-parameter-Wno-unused-parameter ,但请注意,在编译器命令行中,此警告的任何可能的使能标志必须位于此禁用标志之后,才能生效。

在C ++ 11中,可以使用lambdaexpression式( 通过Ben Deane )捕获未使用的variables来形成UNUSEDmacros的替代forms:

 #define UNUSED(x) [&x]{}() 

给出以下示例,应该优化lambdaexpression式的即时调用:

 int foo (int bar) { UNUSED(bar) ; return 0; } 

我们可以在godbolt看到这个呼叫被优化掉了:

 foo(int): xorl %eax, %eax ret 

大多数情况下,使用预处理器指令被认为是邪恶的。 理想情况下,你想避免他们像害虫。 请记住,让编译器理解你的代码很容易,让其他程序员理解你的代码要困难得多。 这样或那样的几十个这样的情况,使得以后或者其他人很难自己去阅读。

一种方法可能是将你的参数放在某种参数类中。 然后你可以只使用variables的一个子集(相当于你的赋值0),或者为每个平台使用该变元类的不同特化。 然而这可能不值得,你需要分析它是否合适。

如果你可以阅读不可能的模板,你可以在“Exceptional C ++”书中find高级技巧。 如果读过你的代码的人可以得到他们的技能来涵盖那本书中所教导的疯狂的东西,那么你将会拥有漂亮的代码,这些代码也可以很容易阅读。 编译器也会很清楚你正在做什么(而不是通过预处理来隐藏所有的东西)

首先警告是由源文件中的variables定义而不是头文件产生的。 标题可以保持原始,应该,因为你可能会使用像doxygen的东西来生成API文档。

我会假设你在源文件中有完全不同的实现。 在这些情况下,您可以注释掉违规参数或只写参数。

例:

 func(int a, int b) { b; foo(a); } 

这可能看起来很神秘,所以定义了一个像UNUSED这样的macros。 MFC做的方式是:

 #ifdef _DEBUG #define UNUSED(x) #else #define UNUSED(x) x #endif 

像这样你可以在debugging版本中看到警告,可能会有所帮助。

C ++ 17现在提供[[maybe_unused]]属性。

http://en.cppreference.com/w/cpp/language/attributes

相当不错,标准。

总是注释掉参数名称是不安全的? 如果不是,你可以做类似的事情

 #ifdef _MSC_VER # define P_(n) n #else # define P_(n) #endif void ProcessOps::sendToExternalApp( QString sAppName, QString sImagePath, qreal P_(qrLeft), qreal P_(qrTop), qreal P_(qrWidth), qreal P_(qrHeight)) 

有点难看。

无macros和可移植的方式来声明一个或多个参数为未使用的:

 template <typename... Args> inline void unused(Args&&...) {} int main(int argc, char* argv[]) { unused(argc, argv); return 0; } 

使用UNREFERENCED_PARAMETER(p)可以工作。 我知道它是在Windows系统的WinNT.h中定义的,也可以很容易地定义为gcc(如果它还没有的话)。

UNREFERENCED PARAMETER(p)被定义为

 #define UNREFERENCED_PARAMETER(P) (P) 

在WinNT.h中。

你可以使用__unused告诉编译器该variables可能不被使用。

 - (void)myMethod:(__unused NSObject *)theObject { // there will be no warning about `theObject`, because you wrote `__unused` __unused int theInt = 0; // there will be no warning, but you are still able to use `theInt` in the future } 

使用编译器的标志,例如GCC的标志: -Wno-unused-variable

这运作良好,但需要C ++ 14我不知道我们是否可以适应与C + + 11的作品

 template <typename ...Args> void UNUSED(Args&& ...args) { (void)(sizeof...(args)); } 

我发现大多数提供的答案只适用于本地未使用的variables,并会导致未使用的静态全局variables的编译错误。

另一个macros需要压制未使用的静态全局variables的警告。

 template <typename T> const T* UNUSED_VARIABLE(const T& dummy) { return &dummy; } #define UNUSED_GLOBAL_VARIABLE(x) namespace {\ const auto dummy = UNUSED_VARIABLE(x);\ } static int a = 0; UNUSED_GLOBAL_VARIABLE(a); int main () { int b = 3; UNUSED_VARIABLE(b); return 0; } 

这是可行的,因为匿名命名空间中的非静态全局variables将不会报告警告。

虽然需要C ++ 11

  g++ -Wall -O3 -std=c++11 test.cpp 

警告我没有看到你的问题。 将其logging在方法/函数头文件中,编译器xy将在这里发出(正确的)警告,但是这些variables是平台z所必需的。

警告是正确的,不需要closures它。 它不会使程序无效 – 但应该logging下来,这是有原因的。