Eclipse CDTが「構文エラー」と言っているのに、コンパイルには問題ないのはなぜですか
-
03-07-2019 - |
質問
私は、次のような文を含む数行の既存のCコードで作業しています:
struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(struct collect_conn, runicast_conn));
構造体collect_connは次の行に沿っています:
struct collect_conn {
struct runicast_conn runicast_conn;
struct announcement announcement;
const struct collect_callbacks *cb;
struct ctimer t;
uint16_t rtmetric;
uint8_t forwarding;
uint8_t seqno;
};
Eclipse CDTを使用していますが、オレンジ色の波線で「シンタックスエラー」とマークされています。 CDTインデクサーによってそのようにマークされていると思います。 ただし、コンパイル(手動での端末)は問題ありません。
ただし、行の要素にはインデックスが付けられないため、これは少し不便です(したがって、呼び出し階層ツリーは常に正しいとは限りません、または要素の強調表示など)
なぜEcipseはそのままのラインを好まないのですか?
解決
Eclipse CDTには、コードを分析してインデックスを作成するための独自のプリプロセッサ/パーサーが含まれています。ただし、ビルドを起動すると、たとえばgccなどのCDTがシステムコンパイラを呼び出します。 CDTパーサーで受け入れられる構文とコンパイラーで受け入れられる構文には、わずかな違いがある場合があります。これが発生すると、CDTパーサーが混乱する可能性があります。
私のシステムでは、 offsetof
マクロは __ offsetof __
キーワードを使用する式に展開されます。このキーワードはCDTによって認識されないため、構文エラーがあります。この問題に対処するために、CDTパーサーには、次のような __ offsetof __
を処理するマクロが組み込まれています。
#define __offsetof__(x) (x)
これは正しいようには見えませんが、少なくとも私のシステムでは、ソースから __ offsetof __
キーワードを削除すると、依然として構文エラーが発生します。
Paths and Symbolsプロパティページに移動して、 'foo'にマップする __ offsetof __
のマクロを追加することで、構文エラーを取り除くことができました。これにより、パーサーは、これまで見たことのない関数の呼び出しだけを考えますが、構文エラーは考えません。
または、ウィンドウ>に移動して、エディターで構文エラーレポートをオフにすることもできます。設定>一般>編集者>テキストエディター> C / C ++インデクサーマーカーの注釈とすべてのチェックボックスをオフにします。
他のヒント
Eclipse CDTの設定-> C / C ++->言語マッピングの問題を修正しました:追加 コンテンツタイプ:Cヘッダー 言語:C ++
CDTパーサーはoffsetof(struct ...)の部分を好まないようです。 typedefを使用してcollect_connを宣言すると、エラーはなくなります。少なくとも私にとっては、次のコードが機能します:
typedef struct {
struct runicast_conn runicast_conn;
struct announcement announcement;
const struct collect_callbacks *cb;
struct ctimer t;
uint16_t rtmetric;
uint8_t forwarding;
uint8_t seqno;
} collect_conn;
...
struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(collect_conn, runicast_conn));
元の宣言を変更できない場合は、次のようにします:
typedef struct collect_conn collect_conn_t;
混乱する可能性があります。 offsetof
たとえば、スコープ内。そうでない場合は、式を単純化して、たとえば #define
の offset
、または何か。
コンパイラは offsetof
の組み込みバージョンを提供するかもしれないと考えていますが、Eclipseのコンパイラ/コードパーサーは提供しないかもしれません。その場合、Eclipseがコードを適切に解析できるように、定義があることを確認する必要があります。
インデクサーを「フルc / C ++インデクサー(完全解析)」に切り替えてみてください。環境設定-> c / C ++->インデクサー
コードはエラーなしでコンパイルされますが、Eclipse CDTのリアルタイムコードアナライザーはC / C ++ファイルにいくつかのエラーを表示する場合があります(例: 'Function xxxを解決できませんでした)。これは、Eclipse CDTがMinGWの(または他のGNUコンパイラ)の代わりに、コードの分析とインデックスの構築に独自のプリプロセッサ/パーサーを使用するためです。ワークスペース内のすべてのEclipseプロジェクトでこれをグローバルに修正するには、次の手順に従います。 (特定のプロジェクトでのみこれを修正するには、メニュー「プロジェクト->設定」の手順1、2、4を実行します)
1-メニュー ' Window-> Preferences-> C / C ++-> Language Mappings 'で、以下に示すように正しいマッピングを追加します(例:コンテンツタイプ:C ++ソース/ヘッダーファイル、GNU C ++言語などを使用) グローバル言語マッピング設定
2-メニュー「 Window-> Preferences-> C / C ++-> Indexer 」で、すべてのチェックボックス(「スキップ」ではない)をチェックして、完全なインデックスを設定します以下: グローバルインデクサーの設定
3-各プロジェクトの特定のプロパティで、メニュー「プロジェクト->プロパティ-> C / C ++全般->インデクサー」で、「プロジェクト固有の設定を有効にする」のチェックを外します。 プロジェクトインデクサーの設定
4-インデックスの再構築、メニュー 'プロジェクト-> C / C ++インデックス->再構築'。
Ivでも同じ問題が発生しました。 offsetofには2つの定義があります(C用とC ++用)。 IMO問題はそこから来ています
たとえば、私が入力した場合
#ifndef __cplusplus
#endif
Eclipseはグレーになります。 __cplusplusが定義されていることを意味しますが、私のプロジェクトはC
残念ながら修正が見つかりません。
新しいCDTプロジェクトウィザードでMakefileプロジェクトの[エラーパーサー]タブをチェックし、CDT Visual Cエラーパーサーを削除した後、同様の問題を修正しました(gccを使用しています)
このような問題を解決することになりました。最初にプロジェクトプロパティを開き、次にC / C ++ general-> Paths and Symbolsカテゴリを開きました。 [シンボル]タブの下に、次のエントリを追加しました。
Symbol: offsetof(TYPE,MEMBER)
Value: ((ssize_t) &((TYPE *)0)->MEMBER)
これらのシンボルはインデクサーによって使用されますが、コンパイラーには渡されません(少なくともMakefileプロジェクトでは、他の種類のCプロジェクトでは試していません)。したがって、GCCの組み込みoffsetof <をオーバーライドしません。 / p>
Eclipseがこれを何度か行うのを見てきましたが、Javaで使用しています。通常、ファイルを閉じて再度開くと、修正されます(間違っているものはすべてリセットされます)。通常はそこにあったエラーのようですが、修正されており、「エラーキャッシュ」正しく更新されていません。