gpt4 book ai didi

c - 警告不是编译时常量的函数参数

转载 作者:太空狗 更新时间:2023-10-29 16:36:22 24 4
gpt4 key购买 nike

假设我正在维护一个接受两个参数的库函数,两个参数都是指针。第二个参数的存在只是为了向后兼容;调用者应始终传递 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);
}

但这不适用于我测试过的任何版本的 GCC。 两个 调用 thefun 时,我都会收到警告。 ( Compiler Explorer demo .)

任何人都可以提出一个替代构造,该构造将为 warning_expected 而不是 warning_not_expected 产生警告吗?

注意事项:

  • 奇怪的是,上面does work如果 b 是一个 int
  • 上面使用了特定于 GCC 的扩展,但是欢迎使用适用于更广泛编译器的解决方案。 (特别是,clang 没有实现 attribute((warning)),而且我还没有找到替代方案。)
  • 在优化关闭时仍然有效的解决方案优于关闭优化的解决方案。 (即使 b 是一个 int 并且 thefun 被标记为始终内联,以上代码在关闭优化的情况下不起作用。)
  • 一种不涉及将 thefun 定义为宏的解决方案优于将其定义为宏的解决方案。
  • 当包含在 C 程序和 C++ 程序中时,头文件必须有效。适量的 ifdeffage 是可以接受的。
  • 它必须是警告,而不是硬错误,除非 -Werror 或等效项处于事件状态。

编辑基于Kamil Cuk's discovery可以通过将指针转换为不同大小的整数 来抑制不需要的警告,我确定这是对 __builtin_constant_pfiled GCC bug report #91554 实现的疏忽.我仍然对提供使用 clang、icc 或通常与 GNU libc 一起使用的任何其他编译器执行此操作的方法的答案感兴趣。

最佳答案

我终于设法让它工作了:

if (!__builtin_constant_p((int)(uintptr_t)b) || b != 0) {

这样你只会收到一个警告。

gcc 似乎无法对指针类型执行 __builtin_constant_p__builtin_constant_p(b) 始终返回 0,因此 warn 函数始终处于链接状态。将 b 转换为 int 奇怪地工作。虽然它失去了指针值的精度,但我们不关心它,因为我们只检查它是否是一个常量。

关于c - 警告不是编译时常量的函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57661132/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com