として@ErikWは_Generic
は、Eclipse CDTのことをC11の機能で、指摘しましたパーサーはまだサポートしていません。 This bugトラックがそれをサポートしています。
(ちなみに、contributionsではCDTのC11サポートをEclipseに非常に歓迎されている!)
マクロを使用してこの問題を回避することが可能です。
"パスとシンボル"にCONVERT(...)
マクロの別のバージョンを定義しようとすると、そこに定義されているマクロがファイルの最上部に書かれているように扱われるという問題があります。その後の実際のコードでの再定義は、「パスとシンボル」の定義を上書きします。
私はこれについて移動するための2つのアプローチを考えることができます。
アプローチ1
CDTは、それがコードを解析だときtrueと評価され、特別なマクロ__CDT_PARSER__
を定義しますが、偽のときコードは実際にコンパイルされます。
あなたはCDTの目的のためにCONVERT(...)
の異なるバージョンを定義するためにこれを利用することができます
#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
が動作します:代わりにCONVERT(...)
の異なるバージョンを定義する
#ifdef __CDT_PARSER__
#define CONVERT(...) 0
#else
...
#endif
アプローチ2
を、私たちは、CDTの目的のために、マクロであることを_Generic(...)
自体を定義することができます。
今度は、「パスとシンボル」でこれを行うことができます。コード内に_Generic(...)
という再定義が含まれていないためです。
シンボルを「パスとシンボル」に定義しましょう。名前は_Generic(...)
、空の値にしてください。
さて、この行:
順次に拡大していきます
void* test = _Generic((FIRST("testme", 42)), \
char* : toText, \
int : toInt, \
) ("testme", 42)
:
("testme", 42)
は、括弧内のコンマとして解析し、解析し(
void* test = ("testme", 42);
void* test = CONVERT("testme", 42);
はに拡大します-expressionであり、したがって有効なイニシャライザです)。
このアプローチには、実際のコードを変更する必要がなく、CONVERT
のマクロではなく_Generic
マクロのすべての使用を処理するという利点があります。
一方、_Generic
マクロの他の用途では、この特定の拡張は解析されない可能性があります。そうであれば、すべての用途のために解析する別の拡張を思いつくことができます。それ以外の場合は、アプローチ1に進むことができます。
'_Generic'はC11標準のものです。私が知っていることから、Eclipseの "intellisense"はまだそれをサポートしていません。 –