由於@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的「智能感知」尚不支持它。 –