如何忽略 third-party headers 中定义的宏的编译器警告?
How to ignore compiler warnings for macros defined in third-party headers?
目前可以告诉编译器忽略来自给定 header 的警告,方法是将其视为“系统 header”,包括通过 -isystem /path/to/dir
的 header。
但是,如果警告源于 header 中定义的 宏 ,这仍然无效。有什么方法可以忽略宏的警告吗?我最感兴趣的是 GCC 和 Clang 解决方案。
以下示例基于 Ubuntu 20.04 上的 Clang 14.0.0 和 GCC 11.1.0:
// include/third_party.h
#pragma once
#define MY_CAST(x) ((int)x)
// main.cpp
#include <third_party.h>
int main()
{
int x = MY_CAST(123);
return x;
}
使用 GCC:
$ g++ -isystem include -Wold-style-cast main.cpp
In file included from main.cpp:1:
main.cpp: In function ‘int main()’:
main.cpp:5:21: warning: use of old-style cast to ‘int’ [-Wold-style-cast]
5 | int x = MY_CAST(123);
| ^~~
使用 Clang:
$ clang++ -isystem include -Wold-style-cast main.cpp
$
适用于 GCC 但不适用于 Clang 的示例:
// include/third_party2.h
#pragma once
struct Foo
{
int x;
int y;
};
#define FOO Foo{.x = 123, .y = 321}
// main.cpp
#include <third_party2.h>
int main()
{
Foo f = FOO;
return f.x;
}
$ g++ -isystem include -pedantic main2.cpp
$
$ clang++ -isystem include -pedantic main2.cpp
main2.cpp:5:13: warning: designated initializers are a C++20 extension [-Wc++20-designator]
Foo f = FOO;
^
include/third_party2.h:9:17: note: expanded from macro 'FOO'
#define FOO Foo{.x = 123, .y = 321}
^
1 warning generated.
不是你要求的,但应该比直接使用编译指示要好。
#define ALLOW_OLD_CAST(...) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wold-style-cast\"") \
__VA_ARGS__ \
_Pragma("GCC diagnostic pop")
然后ALLOW_OLD_CAST( RCC->CR1 |= 0x0001; )
这个问题似乎只是 GCC/Clang 中的一个错误。一般来说,来自系统宏的警告 是 预计会被忽略的,而且大部分都被忽略了。我只是碰巧遇到了不忽略警告的非常具体的用例。
如果有人对 GCC 问题感兴趣,请查看错误报告:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103862
对于 Clang,我在这里问了一个一般性问题:
https://lists.llvm.org/pipermail/cfe-dev/2021-December/069648.html
并在此处报告了问题:
https://github.com/llvm/llvm-project/issues/52944
奖励:为了 clang-tidy,我有一个补丁来确保忽略来自宏的警告:
https://reviews.llvm.org/D116378
感谢大家为本次调查做出的贡献!
目前可以告诉编译器忽略来自给定 header 的警告,方法是将其视为“系统 header”,包括通过 -isystem /path/to/dir
的 header。
但是,如果警告源于 header 中定义的 宏 ,这仍然无效。有什么方法可以忽略宏的警告吗?我最感兴趣的是 GCC 和 Clang 解决方案。
以下示例基于 Ubuntu 20.04 上的 Clang 14.0.0 和 GCC 11.1.0:
// include/third_party.h
#pragma once
#define MY_CAST(x) ((int)x)
// main.cpp
#include <third_party.h>
int main()
{
int x = MY_CAST(123);
return x;
}
使用 GCC:
$ g++ -isystem include -Wold-style-cast main.cpp
In file included from main.cpp:1:
main.cpp: In function ‘int main()’:
main.cpp:5:21: warning: use of old-style cast to ‘int’ [-Wold-style-cast]
5 | int x = MY_CAST(123);
| ^~~
使用 Clang:
$ clang++ -isystem include -Wold-style-cast main.cpp
$
适用于 GCC 但不适用于 Clang 的示例:
// include/third_party2.h
#pragma once
struct Foo
{
int x;
int y;
};
#define FOO Foo{.x = 123, .y = 321}
// main.cpp
#include <third_party2.h>
int main()
{
Foo f = FOO;
return f.x;
}
$ g++ -isystem include -pedantic main2.cpp
$
$ clang++ -isystem include -pedantic main2.cpp
main2.cpp:5:13: warning: designated initializers are a C++20 extension [-Wc++20-designator]
Foo f = FOO;
^
include/third_party2.h:9:17: note: expanded from macro 'FOO'
#define FOO Foo{.x = 123, .y = 321}
^
1 warning generated.
不是你要求的,但应该比直接使用编译指示要好。
#define ALLOW_OLD_CAST(...) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wold-style-cast\"") \
__VA_ARGS__ \
_Pragma("GCC diagnostic pop")
然后ALLOW_OLD_CAST( RCC->CR1 |= 0x0001; )
这个问题似乎只是 GCC/Clang 中的一个错误。一般来说,来自系统宏的警告 是 预计会被忽略的,而且大部分都被忽略了。我只是碰巧遇到了不忽略警告的非常具体的用例。
如果有人对 GCC 问题感兴趣,请查看错误报告: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103862
对于 Clang,我在这里问了一个一般性问题: https://lists.llvm.org/pipermail/cfe-dev/2021-December/069648.html
并在此处报告了问题: https://github.com/llvm/llvm-project/issues/52944
奖励:为了 clang-tidy,我有一个补丁来确保忽略来自宏的警告: https://reviews.llvm.org/D116378
感谢大家为本次调查做出的贡献!