首页 > 解决方案 > 编译时检查枚举成员是否存在

问题描述

这个问题相当理论化,我手头没有现实生活中的例子,只是我遇到过几次,想知道是否有通用的方法来解决。

假设我有一个与公开枚举的库交互的程序。根据库版本,一些枚举成员可能存在,而另一些可能不存在。我想根据它们的存在编译条件代码。我知道还有其他最佳实践,例如#if库版本上的 -ing 。然而,在某些情况下,只检查枚举的存在是最干净和最简单的。

我在声明枚举时看到的一些代码遵循此约定:

enum foo {
    foo_bar = 1
#define foo_bar foo_bar
    foo_baz = 2
#define foo_baz foo_baz
    ...
};

这让我可以#ifdef foo_XXX用来检查是否存在enum foo. 但当然,它并不总是可用。

有没有办法在当前词法范围内测试“名称”的定义?我专门针对枚举,但也接受了更一般的答案:) 我认为没有“标准 C”方法可以这样做,因此也适用仅 GCC 或仅 clang 的解决方案。

编辑:在考虑了一下之后,我实现了一个小的 GCC“内置”,我称之为__builtin_compile_time_ifdef. 它接受名称作为字符串,如果名称已定义,则返回 1。它工作正常。剩下的问题是,在我所知道的所有提供条件评估 ( __builtin_choose_expr, _Generic) 的构造中,仍会检查未评估的分支是否有未声明的名称。所以如果我想使用这个名字(而不仅仅是检查是否存在),我不能。

标签: cgccclang

解决方案


For future reference, I wrote a PoC plugin demonstrating what I needed:

#include <stdio.h>

enum x {
    v1 = 1,
    // v2 = 2
};

void main(void) {
    enum x v1 = (enum x)__builtin_lookup_name("v1", (enum x)-1);
    enum x v2 = (enum x)__builtin_lookup_name("v2", (enum x)-1);

    printf("%d %d\n", v1, v2); // prints "1 -1"
}

推荐阅读