这个问题是理论上的,我手头没有一个现实的例子,这只是我几次遇到的东西,想知道是否有通用的解决方法。
假设我有一个程序与一个暴露枚举的库接口。根据库的版本,某些枚举成员可能存在,而有些可能不存在。
我想根据它们的存在来编译条件代码。我知道库版本上还有其他最佳实践,例如#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的解决方案。
编辑:经过一番思考,我实现了一个名为__builtin_compile_time_ifdef
的小型GCC“内置”。它接受名称作为 string ,如果定义了名称,则返回1。它工作正常。剩下的问题是,在我所知的所有提供条件评估的构造中(__builtin_choose_expr
,_Generic
),仍会检查未评估的分支中是否有未声明的名称。因此,如果我想使用名称(而不只是检查是否存在),就不能使用。
答案 0 :(得分:1)
我从未听说过这种功能,GNU cpp manual没有描述任何类似的功能。确实,在the description of #if
中,他们明确指出enum
常量未被识别。
cpp
不应尝试将其输入解析为C;它仅查找预处理器指令和宏以进行扩展。确实,人们经常使用cpp
来预处理其他语言的代码(例如,汇编语言)。如果预处理器试图识别enum
关键字并解析其语法,则其他语言可能会以完全不同的方式使用字符串enum
的其他语言将其混淆,这与人们的期望相反。因此,我认为没有人会创造您想要的东西。
这是人们应该以其他方式解决的问题(您在已经知道的评论中提到)。
答案 1 :(得分:1)
为了以后参考,我写了a PoC plugin来说明我的需要:
#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"
}