我有一个跨平台的应用程序,在我的几个函数中,并不是所有传递给函数的值都被利用。因此我从GCC得到一个警告,告诉我有未使用的变量。

绕开警告的最佳编码方式是什么?

在函数周围使用#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
{

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

还是把函数末尾的变量赋值为0 ?(我讨厌这样做,因为它改变了程序流中的某些东西,从而使编译器警告静音)。

有正确的方法吗?


当前回答

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

未引用参数(p)定义为

#define UNREFERENCED_PARAMETER(P)          (P)

在WinNT.h。

其他回答

首先,警告是由源文件中的变量定义生成的,而不是头文件。头文件可以保持原始状态,而且应该保持原始状态,因为您可能正在使用类似doxygen的东西来生成api文档。

我假设您在源文件中有完全不同的实现。在这些情况下,您可以注释掉有问题的参数,或者直接写入参数。

例子:

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

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

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

像这样,在调试版本中仍然会看到警告,可能会有帮助。

c++ 17更新

在c++ 17中,我们获得了[[maybe_unused]]属性,该属性包含在[dcl.attr.unused]中。

属性令牌maybe_unused表示一个名称或实体可能是故意未使用的。应当 每个属性列表中最多出现一次,且不允许出现属性参数子句。 ... 例子: [[maybe_unused]] void f([[maybe_unused]] bool thing1, [[maybe_unused]] bool thing2 { [[maybe_unused]] bool b = thing1 && thing2; 断言(b); } 不管是否定义了NDEBUG,实现都不应该警告b未使用。-end示例]

示例如下:

int foo ( int bar) {
    bool unused_bool ;
    return 0;
}

clang和gcc都使用-Wall -Wextra为bar和unused_bool生成诊断。

添加[[maybe_unused]]将使诊断静默:

int foo ([[maybe_unused]] int bar) {
    [[maybe_unused]] bool unused_bool ;
    return 0;
}

现场观看。

在c++ 17

在c++ 11中,可以使用lambda表达式(通过Ben Deane)捕获未使用的变量来形成UNUSED宏的另一种形式:

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

lambda表达式的直接调用应该被优化掉,给出如下示例:

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

我们可以在godbolt中看到调用被优化了:

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

无宏且可移植的声明一个或多个参数为未使用的方法:

template <typename... Args> inline void unused(Args&&...) {}

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

你可以使用__unused来告诉编译器这个变量可能不会被使用。

- (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和Clang中,你可以使用__attribute__((未使用))预处理器指令来实现你的目标。 例如:

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