【问题标题】:Why does this #define STMT ( 0 || g() ) produce a compiler error [-Werror=unused-value]?为什么这个 #define STMT ( 0 || g() ) 会产生编译器错误 [-Werror=unused-value]?
【发布时间】:2019-11-05 16:56:50
【问题描述】:

在使用 Petsc 编译程序的过程中,我偶然发现了一个类似于以下的构造。据我所知,在 Petsc 中,他们使用它来包装对 MPI 的调用,以便使用集体通信监视对函数的调用。

#include <stdio.h>

int f() {return 0;}
int g() {printf("g()\n");return 0;}

#define STMT (  0  || g() )

int main()
{
                STMT;
                printf("main()\n");
                return 0;
}

用 gcc 编译:

gcc -Wall -Werror ./test.c

引发以下错误/警告:

./test.c:7:20: error: value computed is not used [-Werror=unused-value]
 #define STMT (  0  || g() )
              ~~~~~~^~~~~~~~
              ./test.c:11:3: note: in expansion of macro ‘STMT’
                 STMT;
                    ^~~~
                    cc1: all warnings being treated as errors

为什么编译器会发出这个警告?恕我直言 g() 始终执行并且始终使用计算的值。

注意:测试:gcc 版本 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)、gcc 版本 8.3 和 gcc 版本 9

【问题讨论】:

  • “计算值”指的是整个括号表达式,而不仅仅是g()
  • 看起来您的警告已升级为错误。

标签: c gcc gcc-warning


【解决方案1】:

编译器告诉你(0 || g()) 的值没有被使用,这是真的。你不会对|| 的结果做任何事情。要解决此问题,您应该将结果转换为 void,如下所示:

#define STMT (void)(  0  || g() )

【讨论】:

  • 好的,我明白了。这修复了警告并且是一个明智的编译器警告。 Petsc 中的调用如下所示: ((petsc_allreduce_ct += PetscMPIParallelComm((comm)),0) || MPI_Bcast((buffer),(count),(datatype),(root),(comm))) 。我是否正确地假设他们使用这个构造来增加 petsc_allreduce_ct 每当调用 MPI_Bcast 并且不再使用整个语句的最终值(始终为 1 ?)?
  • 我从未使用过该库,但基于MPI_Bcast,结果将是truefalse。按顺序计算两个表达式似乎是一种技巧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
相关资源
最近更新 更多