zwo*_*wol 14 c gcc compiler-warnings
假设我正在维护一个接受两个参数(两个指针)的库函数。第二个参数仅是为了向后兼容而存在。调用者应始终传递NULL。我想在我的头文件中放入一些内容,如果第二个参数不是编译时常量NULL,则会使编译器发出警告。我以为我可以使用GCC __builtin_constant_p和__attribute__((warning))扩展名来做到这一点:
extern void thefun_called_with_nonnull_arg (void)
__attribute__((__warning__(
"'thefun' called with second argument not NULL")));
extern int real_thefun (void *, void *);
static inline int
thefun (void *a, void *b)
{
if (!__builtin_constant_p(b) || b != 0)
thefun_called_with_nonnull_arg();
return real_thefun(a, b);
}
int warning_expected (void *a, void *b)
{
return thefun(a, b);
}
int warning_not_expected (void *a)
{
return thefun(a, 0);
}
Run Code Online (Sandbox Code Playgroud)
但这不适用于我测试过的任何版本的GCC。两次致电我都会收到警告thefun。(编译器资源管理器演示。)
谁能建议一种替代构造,它会为warning_expected而不是发出警告warning_not_expected?
笔记:
bintattribute((warning)),我也没有运气找到替代方法。)b是int且thefun标记为始终在线,以上功能也无法关闭优化功能。)thefun为宏的解决方案比包含宏的解决方案更为可取。-Werror有效,否则它必须是警告,而不是硬错误。编辑:基于卡米尔·库克(Kamil Cuk)的发现,可以通过将指针强制转换为不同大小的整数来抑制不必要的警告,我确定这是对实施中的疏忽,__builtin_constant_p并提交了GCC错误报告#91554。我仍然对提供使用clang,icc或与GNU libc一起使用的任何其他编译器执行此操作的方式的答案感兴趣。
我终于设法让它发挥作用:
if (!__builtin_constant_p((int)(uintptr_t)b) || b != 0) {
Run Code Online (Sandbox Code Playgroud)
这样您只会收到一个警告。
似乎gcc不能__builtin_constant_p在指针类型上执行。总是__builtin_constant_p(b)返回0,所以警告函数总是链接的。铸造b到int奇怪的作品。尽管它会丢失指针值的精度,但我们并不关心它,因为我们只检查它是否是常量。