gcc 静态Assert检查变量名是否在当前范围中定义

mhd8tkvw  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(159)

我正在定义一个像下面这样的宏,我的目标是完成TODO

#define TEST(_expr, args...) \
    do { \
        // TODO _Static_assert to make sure __xyz is not declared \
        int __xyz = _expr; \
        if (__xyz < 0) { \
            // do some error handling stuff utilizing args and __xyz \
        } \
    } while (0)

宏运行_expr(通常是一个函数调用),并在失败的情况下做一些错误处理。所做填充利用__xyzargs...。极端情况是,使用此宏的开发人员可能在更高的作用域上定义了变量__xyz,并将其作为args...之一传递。这里有一个例子。

int foo(void);
int bar() {
    int __xyz;
    // .... some lines of code
    TEST(foo(), x, y, z, __xyz);
    // .... some more lines of code
    return 0;
}

在本例中,将存在一个静默问题。我想使用_Static_assert来确保没有变量__xyz被定义在任何父作用域中。基本上,宏TEST会在上面的函数中导致编译时错误,因为__xyz是在作用域的开始定义的。

  • 这可行吗?如果是这样,怎么做?
  • 如果这是不可行的,我怎么能避免这样的一个角落的情况?

从理论上讲,这应该是可能的,因为是否在某行声明/定义某个字是编译时信息。
提前感谢大家!!

p8ekf7hl

p8ekf7hl1#

尽管@aschepler的评论实际上是足够的,但从技术上讲,它并不是无懈可击的。我的强迫症给了我这个答案。我们可以使用-Wshadow并将其视为宏中的错误

#define TEST(_expr, args...) \
    do { \
        _Pragma(GCC diagnostic push) \
        _Pragma(GCC diagnostic error "-Wshadow") \
        int TEST_MACRO_PV_xyz = _expr; \
        _Pragma(GCC diagnostic pop) \
        if (TEST_MACRO_PV_xyz < 0) { \
             handle_and_propagate_error(TEST_MACRO_PV_xyz, ##args); \
        } \
    } while (0)

请注意,对于不同的编译器和不同的版本,您需要以不同的方式启用/禁用此错误。

相关问题