我如何最好沉默关于未使用的变量警告?我如何最好沉默关于未使用的变量警告?(How do I best

2019-05-05 22:26发布

我有一个跨平台的应用程序,并在我的几个函数传递并不是所有的值被利用的功能。 因此,我从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
{

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

还是我在函数结束赋值零的变量? (我讨厌,因为它改变的东西在程序流程沉默编译器警告)。

是否有一个正确的方法是什么?

Answer 1:

你可以把它放在“ (void)var; ”表达 (什么都不做),这样一个编译器看到它被使用。 这是编译器之间进行移植。

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);
}


Answer 2:

In GCC and Clang you can use the __attribute__((unused)) preprocessor directive to achieve your goal.
For example:

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


Answer 3:

您当前的解决方案是最好的 - 注释掉的参数名称,如果你不使用它。 这适用于所有的编译器,所以你不必使用预处理器为GCC做专。



Answer 4:

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

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

相当不错的标准。



Answer 5:

一个同事刚刚向我指出这个可爱的小宏在这里

为了便于我将包括下列宏。

#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))


Answer 6:

另一个更好的办法是注释掉的变量名:

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


Answer 7:

GCC在默认情况下不会标记这些警告。 此警告必须已打开明确地通过传递-Wunused-parameter通过传递给编译器或隐含-Wall -Wextra (或可能标志的一些其他组合)。

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



Answer 8:

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; assert(b); } 

实现不应该警告b为未使用,NDEBUG是否被定义。 末端示例]

对于下面的例子:

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

无论铛和gcc使用-Wall -Wextra两个酒吧unused_bool生成诊断( 亲身体验 )。

同时加入[[maybe_unused]]沉默诊断:

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

在现场观看 。

之前,C ++ 17

在C ++ 11的另一种形式UNUSED宏可以使用lambda表达式(形成通过本迪恩 )与未使用的变量的捕获:

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

λ表达式的直接调用应被优化掉,给出下面的例子:

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

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

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


Answer 9:

声明一个或多个参数作为未使用的宏以下,可移植的方式:

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

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


Answer 10:

使用预处理指令被认为是邪恶的大部分时间。 理想情况下,你想避免他们像佩斯。 请记住,使编译器理解你的代码是很容易,让其他程序员了解您的代码更难。 几十个类似案例,在这里和那里使它很难后来还是为别人,现在看自己。

一种方式是把你的参数汇集成某种参数类的。 然后,您可以只使用变量的一个子集(相当于你分配0真的),或具有每个平台参数类的不同专业。 这可能但不值得,你需要分析它是否适合。

如果你可以看到是不可能的模板,你可能会发现在“例外C ++”一书的高级技巧。 如果谁还会看你的代码的人可以得到他们的技能涵盖在这本书教疯狂的东西,那么你就拥有漂亮的代码也可轻松读取。 编译器也将是心知肚明的你在做什么(而不是躲在通过预处理的一切)



Answer 11:

第一关闭警告由源文件不是标题文件中的变量定义中产生。 头可以保持原始的和应该的,因为你可能会使用就像doxygen的东西生成API文档。

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

例:

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

这似乎是神秘,所以定义一个宏像使用。 该方法MFC做的是:

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

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



Answer 12:

这难道不是安全总是注释掉参数的名字呢? 如果不是,你可以这样做

#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))

这是一个有点不太难看。



Answer 13:

使用UNREFERENCED_PARAMETER(p)可以工作。 我知道这是在WINNT.H中定义的Windows系统,可以很容易地为GCC定义以及(如果还没有的话)。

UNREFERENCED PARAMETER(p)被定义为

#define UNREFERENCED_PARAMETER(P)          (P)

在WINNT.H。



Answer 14:

您可以使用__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
}


Answer 15:

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



Answer 16:

在C ++ 11,这是我使用的解决方案:

template<typename... Ts> inline void Unreferenced(Ts&&...) {}

int Foo(int bar) 
{
    Unreferenced(bar);
    return 0;
}

int Foo2(int bar1, int bar2) 
{
    Unreferenced(bar1, bar2);
    return 0;
}

验证启用优化时要携带(至少在现代MSVC,铛和gcc),而不是产生额外的代码。 由于没有优化,多余的函数调用,执行和参数引用复制到堆栈,但目前还没有涉及到宏。

如果额外的代码是一个问题,你可以使用这个声明来代替:

(decltype(Unreferenced(bar1, bar2)))0;

但在这一点上,宏提供更好的可读性:

#define UNREFERENCED(...) { (decltype(Unreferenced(__VA_ARGS__)))0; }


Answer 17:

这种运作良好,但需要C ++ 11

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


Answer 18:

我发现大部分呈现答案的工作仅为本地未使用的变量,并会导致编译错误未使用的静态全局变量。

另一个宏需要抑制未使用的静态全局变量的警告。

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;
}

这工作,因为没有警告将被报告为匿名命名空间的非静态全局变量。

C ++ 11虽然需要

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


Answer 19:

我没有看到警告你的问题。 文件就可以在方法/函数头是编译器XY将在这里发出一个(正确的)警告,但论文所需的平台ž变量。

该警告是正确的,没有必要将其关闭。 这并不能否定程序 - 但它应记录在案,这是有原因的。



文章来源: How do I best silence a warning about unused variables?