为什么这个 #define STMT ( 0 || g() ) 会产生编译器错误 [-Werror=unused-value]?

Why does this #define STMT ( 0 || g() ) produce a compiler error [-Werror=unused-value]?

在使用 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

提出以下 error/warning:

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

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

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