Suppress unused variable warning in C++ => Compiler bug or code bug?

怎甘沉沦 提交于 2019-11-30 18:08:09

The actual way of indicating you don't actually use a parameter is not giving it a name:

int f(int a, float) {
     return a*2;
}

will compile everywhere with all warnings turned on, without warning about the unused float. Even if the argument does have a name in the prototype (e.g. int f(int a, float f);), it still won't complain.

I'm not 100% sure that this is portable, but this is the idiom I've usually used for suppressing warnings about unused variables. The context here is a signal handler that is only used to catch SIGINT and SIGTERM, so if the function is ever called I know it's time for the program to exit.

volatile bool app_killed = false;
int signal_handler(int signum)
{
    (void)signum; // this suppresses the warnings
    app_killed = true;
}

I tend to dislike cluttering up the parameter list with __attribute__((unused)), since the cast-to-void trick works without resorting to macros for Visual C++.

It is a compiler bug and there are no known work arounds:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42655

It is fixed in v4.4.

In GCC, you can define a macro as follows:

#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 

Any parameters marked with this macro will suppress the unused warning GCC emits (and renames the parameter with a prefix of UNUSED_). For Visual Studio, you can suppress warnings with a #pragma directive.

The answer proposed by haavee (amended by ur) is the one I would normally use:

int f(int a, float /*epsilon*/) {
     return a*2;
}

The real problem happens when the argument is sometimes but not always used in the method, e.g.:

int f(int a, float epsilon) {
#ifdef LOGGING_ENABLED
     LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
     return a*2;
}

Now, I can't comment out the parameter name epsilon because that will break my logging build (I don't want to insert another #ifdef in the argument list because that makes the code much harder to read).

So I think the best solution would be to use Tom's suggestion:

int f(int a, float epsilon) {
(void) epsilon;    // suppress compiler warning for possibly unused arg
#ifdef LOGGING_ENABLED
     LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
     return a*2;
}

My only worry would be that some compilers might warn about the "(void) epsilon;" statement, e.g. "statement has no effect" warning or some such - I guess I'll just have to test on all the compilers I'm likely to use...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!