抑制 C++ 中未使用的变量警告=>编译器错误还是代码错误?

发布于 2024-08-15 01:23:06 字数 915 浏览 4 评论 0原文

目前,我正在使用以下函数模板来抑制未使用的变量警告:

template<typename T>
void
unused(T const &) {
  /* Do nothing. */
}

但是,当从 Linux 移植到 cygwin 时,我现在在 g++ 3.4.4 上遇到编译器错误(在 linux 上我是 3.4.6,所以也许这是一个错误)修复?):

Write.cpp: In member function `void* Write::initReadWrite()':
Write.cpp:516: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool'
../../src/common/Assert.h:27: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]'
make[1]: *** [ARCH.cygwin/release/Write.o] Error 1

使用的参数是一个成员变量,声明为:

  volatile bool readWriteActivated;

这是编译器错误还是我的代码中的错误?

这是最小的测试用例:

template<typename T>
void unused(T const &) { }

int main() {
  volatile bool x = false;
  unused(!x); // type of "!x" is bool
}

Presently, I am using the following function template to suppress unused variable warnings:

template<typename T>
void
unused(T const &) {
  /* Do nothing. */
}

However, when porting to cygwin from Linux, I am now getting compiler errors on g++ 3.4.4 (On linux I am 3.4.6, so maybe this is a bug fix?):

Write.cpp: In member function `void* Write::initReadWrite()':
Write.cpp:516: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool'
../../src/common/Assert.h:27: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]'
make[1]: *** [ARCH.cygwin/release/Write.o] Error 1

The argument to unused is a member variable declared as:

  volatile bool readWriteActivated;

Is this a compiler bug or a bug in my code?

Here is the minimal test case:

template<typename T>
void unused(T const &) { }

int main() {
  volatile bool x = false;
  unused(!x); // type of "!x" is bool
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忆梦 2024-08-22 01:23:06

指示您实际上没有使用参数的实际方法不是给它一个名称:

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

将在所有警告打开的情况下在任何地方进行编译,而不警告有关未使用的浮点数。即使参数在原型中确实有一个名称(例如int f(int a, float f); ),它仍然不会抱怨。

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.

高冷爸爸 2024-08-22 01:23:06

我不能 100% 确定这是可移植的,但这是我通常用来抑制有关未使用变量的警告的习惯用法。这里的上下文是一个信号处理程序,仅用于捕获 SIGINTSIGTERM,因此,如果该函数被调用,我知道该程序该退出了。

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

我不太喜欢用 __attribute__((unused)) 来弄乱参数列表,因为强制转换为 void 技巧无需借助 Visual C++ 的宏即可发挥作用。

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++.

清欢 2024-08-22 01:23:06

这是一个编译器错误,没有已知的解决方法:

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

在 v4.4 中已修复。

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.

请你别敷衍 2024-08-22 01:23:06

在 GCC 中,您可以按如下方式定义宏:

#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 

任何标有此宏的参数都将抑制 GCC 发出的未使用警告(并使用前缀 UNUSED_ 重命名该参数)。对于 Visual Studio,您可以使用 #pragma 指令抑制警告。

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.

女皇必胜 2024-08-22 01:23:06

haavee 提出的答案(由 ur 修改)是我通常使用的答案:

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

真正的问题发生在参数有时但并不总是在方法中使用时,例如:

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

现在,我不能注释掉参数名称 epsilon,因为这会破坏我的日志记录构建(我不想在参数列表中插入另一个 #ifdef,因为这会使代码更难阅读)。

所以我认为最好的解决方案是使用汤姆的建议:

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

我唯一担心的是某些编译器可能会警告“(void) epsilon;”声明,例如“声明无效”警告或类似的警告 - 我想我只需要在我可能使用的所有编译器上进行测试......

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文