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

StackOverflow https://stackoverflow.com/questions/802410

  •  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 содержит собственный препроцессор/парсер для анализа вашего кода и построения индекса.Однако, когда вы вызываете сборку, CDT вызывает ваш системный компилятор, например, gcc.Между синтаксисом, принимаемым анализатором CDT, и синтаксисом, принимаемым вашим компилятором, могут быть незначительные различия.Когда это происходит, анализатор CDT может запутаться.

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

#define __offsetof__(x) (x)

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

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

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

Другие советы

Я исправил проблему в eclipse CDT с помощью Preferences->C/C++->Language Mappings:Добавить тип контента:Язык C-заголовок:С++

Кажется, анализатору CDT не нравится часть offsetof(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;

Это может быть путано, проверьте, есть ли у вас определение смещение например, в рамках.В противном случае вы можете попытаться упростить выражение, разбив его, например.а #define с offset или что-то в этом роде.

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

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

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

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

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

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

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

У меня та же проблема.Существует два определения offsetof (одно для C и одно для C++).ИМХО, проблема в этом

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

#ifndef __cplusplus
#endif

Затмение сделает его серым.Это означает, что __cplusplus определен, но мой проект — C.

К сожалению, я не нашел решения.

Я исправил аналогичную проблему после проверки вкладки «Парсеры ошибок» в проекте Makefile в мастере нового проекта CDT, удалив анализатор ошибок CDT Visual C (я использую gcc)

В итоге я решил проблему следующим образом.Сначала я открыл свойства проекта, затем категорию «Общие C/C++» -> «Пути и символы».На вкладке «Символы» я добавил эту запись:

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top