使用_Generic关键字的Eclipse的CDT语法错误
我正在使用内置CDT 9.3.0的Oxygen。使用_Generic关键字的Eclipse的CDT语法错误
当我使用我定义的使用_Generic的宏时,所有这些宏用法都带有“语法错误”的下划线,但项目编译正常(设置为使用我的makefile)。
在阅读similar这样的问题之后,由于_Generic从C11开始可能不被eclipse的代码分析支持,我试着为我的宏定义定义一个符号来清空它,但它不起作用。 (在项目设置中,C/C++常规 - >路径和符号 - >符号选项卡,GNU C,添加了符号CONVERT(...)而没有值并添加了符号CONVERT(X),并且CONVERT()和CONVERT没有值)。
例如我的宏:
#define FIRST_(_1, ...) _1
#define FIRST(...) FIRST_(__VA_ARGS__, _1, _2, _3)
#define CONVERT(...) \
_Generic((FIRST(__VA_ARGS__)), \
char* : toText, \
int : toInt, \
) (__VA_ARGS__)
和使用点,即给出了语法错误:
void* test = CONVERT("testme");
由于@ErikW指出,_Generic
是C11功能,它的Eclipse CDT的解析器尚不支持。 This bug跟踪添加对它的支持。
(顺便说一句,contributions到Eclipse CDT的C11支持是非常欢迎!)
它可以解决此使用宏。
试图在“路径和符号”中定义CONVERT(...)
宏的另一个版本的问题是,在那里定义的宏被视为您将它们写在文件的最顶端。随后在实际代码中重新定义将覆盖“路径和符号”中的定义。
我能想到的两种方法去了解这一点:
方法1
CDT定义了一个特殊的宏__CDT_PARSER__
时,它的解析代码,计算结果为真实的,但假的当代码实际上是编译的。
你可以利用这种方法来定义不同版本的CONVERT(...)
对CDT的目的:
#ifdef __CDT_PARSER__
#define CONVERT(...)
#else
#define CONVERT(...) \
_Generic((FIRST(__VA_ARGS__)), \
char* : toText, \
int : toInt, \
) (__VA_ARGS__)
#endif
这几乎工作,但不完全是。我们还得到一个语法错误,因为该行:
void* test = CONVERT("testme", 42);
现在将扩大到:
void* test = ;
正如你所看到的,我们实际上并不想为CONVERT(...)
闲置的扩充。我们需要一个将作为变量初始值设定项解析的扩展。0
将工作:
#ifdef __CDT_PARSER__
#define CONVERT(...) 0
#else
...
#endif
方法2
而不是定义不同版本的CONVERT(...)
的,我们可以定义_Generic(...)
本身成为CDT的目的宏。
这一次,我们可以在“路径和符号”中做到这一点,因为在代码中没有对_Generic(...)
进行重新定义。
所以,让我们定义一个符号“路径和符号”,以_Generic(...)
的名称和空值。
现在,这条线:
void* test = CONVERT("testme", 42);
将扩大到:
void* test = _Generic((FIRST("testme", 42)), \
char* : toText, \
int : toInt, \
) ("testme", 42)
这将反过来扩大到:
void* test = ("testme", 42);
,它解析(("testme", 42)
解析为一个括号逗号-expression,因此是一个有效的初始化)。
此方法的优点是不需要修改实际代码,并且它可以处理_Generic
宏的所有用法,而不仅仅是CONVERT
中的那个。
另一方面,对于_Generic
宏的其他用途,这种特殊扩展可能不会被解析。如果是这样的话,你也许可以想出一个不同的扩展,将分析各种用途,否则你可以用接近1
'_Generic'是从C11的标准去。据我所知,Eclipse的“智能感知”尚不支持它。 –