Странное отсутствие связи между Eclipse CDT, включенными системными заголовками и базовой сборкой C

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

Eclipse 3.7.1 (Indigo SR1) для разработчиков C / C ++ Linux, 64-разрядная версия Ubuntu 10.10

Все началось, когда я импортировал существующий проект, который «работает» сам по себе: я думал, что Eclipse поможет значительно в навигации по файлам и выяснении того, что делает. Однако некоторые из системных заголовков #include d, казалось, не имели правильного эффекта в представлении Eclipse. Это было очень загадочно, и в ходе исследования мне удалось воссоздать проблему в крошечной песочнице.

Шаг первый: Создайте новый проект C ( Файл: Новый: Проект C ), используя образец Hello World ANSI C Project . Параметры: Исполняемый файл: Hello World ANSI C Project / Linux GCC , оставшиеся Пустые проекты установлены на Linux GCC и GNU Autotools установлено значение Hello World ANSI C Autotools Project . Назовите это "привет". Обязательно сгенерируйте make-файл автоматически (расширенные настройки, я считаю, что это значение по умолчанию).

Шаг второй: Настройте путь включения. Использование Project: Свойства: C / C ++ Общие: Пути и символы: Включает: GNU C , установите путь поиска на / usr / local / include , / usr / lib /gcc/x86_64-linux-gnu/4.4.5/include , / usr / include . Второй путь зависит от установленной вами версии gcc. Это не имеет большого значения, если путь сборки включает как минимум / usr / include .

Теперь, если вы откроете hello.c , он будет выглядеть очень просто, и Eclipse будет вполне доволен, за исключением return EXIT_SUCCESS; , который не может разрешить EXIT_SUCCESS . Замените EXIT_SUCCESS нулем ( 0 ), и Eclipse выдаст полную очистку. Выберите Project: Build Project , чтобы сгенерировать исполняемый файл.

Откройте окно командной строки и перейдите к подпапке hello / Debug папки рабочего пространства Eclipse . Оказавшись там, вы можете запустить исполняемый файл со строкой ./ hello .

Теперь начинается самое интересное. Измените hello.c , чтобы он читался во второй части:

#include <fcntl.h>
int main(void) {
    printf("Hello World!\n");

    int zz = SPLICE_F_MOVE;
    printf("zz (SPLICE_F_MOVE) is '%d'\n", zz);

    printf("Bye World!\n");
    return 0;
}

Вы получите сообщение об ошибке в строке int zz ... : «Символ 'SPLICE_F_MOVE' может не подлежит разрешению ». Если вы выполните сборку проекта, вы получите аналогичную ошибку в представлении консоли: «ошибка: 'SPLICE_F_MOVE' undeclared» .

Теперь, если вы измените преамбулу на:

#define _GNU_SOURCE
#include <fcntl.h>

Вы по-прежнему получите ошибку в строке int zz (в редакторе), но проект будет построен правильно! Вы можете подтвердить это, запустив двоичный файл в окне командной строки, которое вы открыли ранее. Это действительно странно, поскольку изучение /usr/include/fcntl.h покажет, что он #include s , и что последний заголовок #define s SPLICE_F_MOVE (и ряд других) в блоке, охраняемом #ifdef __USE_GNU ( __ USE_GNU получает ] #define d, если _GNU_SOURCE равно #define d). Почему наш #define _GNU_SOURCE не распространяется должным образом в перспективе рабочей области?

Итак, это моя проблема в двух словах: почему редактор (и все Eclipse CDT) сообщает об ошибке (очевидно, отказавшись правильно обработать включение), но что базовая сборка завершается успешно?

9
задан Urhixidur 12 December 2011 в 20:43
поделиться