为什么这个 #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() )
在使用 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() )