Почему Eclipse CDT говорит: "синтаксическая ошибка", но компиляция не проблема

Я работаю в существующем коде 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 не нравится линия, как она есть?

10 ответов


Eclipse CDT содержит собственный препроцессор / анализатор для анализа кода и построения индекса. Однако при вызове сборки CDT вызывает системный компилятор, например gcc. Там могут быть незначительные различия между синтаксисом принято парсер ЦДТ и синтаксис принимается компилятором. Когда это происходит, анализатор CDT может запутаться.

на моей системе offsetof макрос расширяется в выражение, которое использует __offsetof__ ключевое слово. Это ключевое слово не распознается CDT, поэтому возникает синтаксическая ошибка. Для решения этой проблемы синтаксический анализатор CDT имеет встроенный макрос для работы с __offsetof__ выглядит так:

#define __offsetof__(x) (x)

это не кажется правильным, по крайней мере, в моей системе результатом является удаление __offsetof__ ключевое слово из источника, которое по-прежнему приводит к синтаксической ошибке.

я смог избавиться от синтаксической ошибки, Перейдя на страницу свойств пути и символы и добавив макрос для __offsetof__ что карты в 'Foo'. Это обманывает парсер, думая, что это просто вызов функции, которую он не видел раньше, но не синтаксическая ошибка.

кроме того, вы можете отключить отчеты об ошибках синтаксиса в Редакторе, перейдя в окно > Настройки > Общие > Редакторы > текстовые редакторы > аннотации и сняв все флажки для маркеров индексатора C/C++.


я исправил проблему в eclipse CDT с настройками - >C / C++->языковые сопоставления : добавить Тип контента : с-заголовка Язык : C++


похоже, синтаксическому анализатору CDT не нравится смещение части(struct ...). Если вы объявите collect_conn с помощью typedef, ошибка исчезнет. По крайней мере, для меня работает следующий код:

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 in-scope, например. В противном случае вы можете попытаться упростить выражение, разбив его, например, на #define С offset или что-то в этом роде.

Я думаю, что компилятор может предоставить встроенную версию offsetof, а компилятор/код-парсер затмений не. Если это так, вам нужно будет убедиться, что у вас есть определение, чтобы Eclipse мог правильно проанализировать ваш код.


попробуйте переключить индексатор на " полный индексатор c / C++ (полный анализ)" в настройках->c/C++ -> indexer


Iv получил ту же проблему. Существует 2 определения смещения (одно для C и одно для C++). IMO проблема исходит из этого

например, если я наберу

#ifndef __cplusplus
#endif

Eclipse будет серым. Это означает, что _ _ cplusplus определен, но мой проект является C

к сожалению, я не нахожу, что исправить.


я исправил аналогичную проблему после проверки синтаксических анализаторов ошибок вкладки в проекте Makefile в новом Мастере проекта CDT, удалив синтаксический анализатор ошибок CDT Visual C (я использую gcc)


в итоге я решил проблему следующим образом. Сначала я открыл свойства проекта, затем категорию C/C++ general->Paths and Symbols. На вкладке символы я добавил следующую запись:

Symbol: offsetof(TYPE,MEMBER)
Value: ((ssize_t) &((TYPE *)0)->MEMBER)

эти символы используются индексатором, но не передаются компилятору (по крайней мере, в проектах Makefile, я не пробовал его в другом виде проекта C), поэтому он не переопределяет встроенный offsetof


иногда, хотя код компилируется без ошибок, анализатор кода реального времени eclipse CDT показывает некоторые ошибки в файлах C/C++ (например. Функция xxx не может быть разрешена). Это связано с тем, что eclipse CDT использует свой собственный препроцессор/парсер для анализа кода и построения индексов вместо MinGW (или любого другого компилятора GNU). Чтобы исправить это глобально для всех проектов eclipse в рабочей области, выполните следующие действия: (Чтобы исправить это только для конкретного проекта, выполните следующие действия 1, 2 и 4 в меню '-1 - >Настройки')

1-в меню 'Окно - > Настройки - >C / C++ - >Языковые Сопоставления' укажите корректные сопоставления, как показано ниже: (например. для типов контента: исходный / заголовочный файл c++, используйте язык GNU C++ и так далее) Настройки Глобальных Языковых Сопоставлений

2-в меню 'Окно - > Настройки - >C / C++ - >Индексатор', установите полную индексацию, установив все флажки (но не "пропустить"), как показано в под: Глобальные Настройки Индексатора

3-в конкретных свойствах каждого проекта, menu'проект - >свойства - >C/C++ general - >индексатор', снимите флажок "Включить конкретные параметры проекта" , как показано ниже: Настройки Индексатора Проекта

4-перестроить индексацию, меню'Проект - >Индекс C/C++ - >Перестроить'.


Я видел, как Eclipse делает это несколько раз, и я использую его для Java. Обычно закрытие и открытие файла снова исправляет его для меня (сбрасывает все, что не так). Обычно кажется, что это ошибка, которая была там, но была исправлена, и "кэш ошибок" не обновляется правильно.