реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Нубовопрос по препроцессору GCC
flopix
сообщение Jul 12 2013, 04:14
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 21-06-12
Пользователь №: 72 429



Используется среда CoCoox, компилятор GCC (Си)

Что то я запутался в препроцессоре, а точнее в работе с #include. Помогите разобраться. Создал для теста пустой проект. Листинг ниже.

main.h
Код
#define testdef



main.c
Код
#include "main.h"
#include "func.h"

#ifndef testdef
    #error testdef not def
#endif

int main(void)
{

    while(1)
    {

    }
}



func.h
Код
#ifndef testdef
    #error testdef not def
#endif



func.c
Код
#include "func.h"

#ifndef testdef
    #error testdef not def
#endif




При компиляции получаю следущее
[cc] Parsing ..\..\..\main.c
[cc] Parsing ..\..\..\func.h
[cc] 0 files are up to date.
[cc] 2 total files to be compiled.
[cc] 1 files to be recompiled from dependency analysis.
[cc] arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Wall -ffunction-sections -g -O0 -c -DSTM32F407VG -DSTM32F4XX -IC:\CooCox\CoIDE\workspace -IC:\CooCox\CoIDE\workspace\testinclude -IC:\CooCox\CoIDE C:\CooCox\CoIDE\workspace\testinclude\main.c C:\CooCox\CoIDE\workspace\testinclude\func.c
[cc] In file included from C:\CooCox\CoIDE\workspace\testinclude\func.c:1:0:
[cc] C:\CooCox\CoIDE\workspace\testinclude\func.h:2:2: error: #error testdef not def
[cc] C:\CooCox\CoIDE\workspace\testinclude\func.c:4:3: error: #error testdef not def



Вопрос в следующем. Почему идентификатор testdef не доступен хотя бы в файле func.h ведь препроцессор при директиве #include "func.h" вставляет его текст непосредственно в листинг. А 2мя строчками ниже в main.c этот идентификатор доступен. Что я упустил?


Кстати если в main.c заменить #include "func.h" на #include "func.c" то в func.c testdef оказывается доступной.

Сообщение отредактировал flopix - Jul 12 2013, 04:21
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Jul 12 2013, 05:50
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Потому что такие правила в С. Большинство идентификаторов доступны только после своего объявления...

ЗЫ Лучше всеж начать с прочтения любой книжки sm.gif, а то экспериментировать замучаетесь. Там заодно и всякие неочевидные вещи разжевываются...
Go to the top of the page
 
+Quote Post
msalov
сообщение Jul 12 2013, 06:22
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



testdef у вас объявлето только в main.h
func.c и func.h не включают main.h, по этому они и выдают ошибку.
Что бы макрос был доступен во всех компилируемых объектах надо заголовочный файл с его объявлением включить во все файлы либо скормить компилятору дополнительную опцию "-Dtestdef"
Go to the top of the page
 
+Quote Post
flopix
сообщение Jul 12 2013, 06:24
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 21-06-12
Пользователь №: 72 429



Ну я как бы и объявляю в самом начале еще до #include "func.h". Почему в "func.h" не видит это определение?

Если можно посовтеуйте норм книгу по этой теме. А то есть кгига по с++ и там только общие вопросы по работе с препроцессором. Тонкости видимости идентификатор в разных модулях не расписаны.
Go to the top of the page
 
+Quote Post
msalov
сообщение Jul 12 2013, 06:31
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(flopix @ Jul 12 2013, 09:24) *
Ну я как бы и объявляю в самом начале еще до #include "func.h". Почему в "func.h" не видит это определение?

Последняя и предпоследняя ошибки являются следствием одного: вы не включили main.h в func.h
Общее правило: если в h или c-файле используется тип, переменная, функция или макрос, эти файлы должны явно включать заголовочный файл где он (тип, переменная, функция или макрос) объявлен.
Ну и конечно же вам надо в заголовочные файлы добавить include-guard
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 12 2013, 06:59
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (flopix @ Jul 12 2013, 08:24) *
Ну я как бы и объявляю в самом начале еще до #include "func.h". Почему в "func.h" не видит это определение?
Потому что каждый файл *.c компилируется отдельно от других (это называется "раздельная компиляция"), а потом результаты этих компиляций объединяются линкером в один выходной файл. И при компиляции func.c компилятор видит только то, что находится в func.c и понятия не имеет, что находится внутри main.c. Его даже не волнует, что main.c вообще существует.

P.S. вы до этого не в CodeVision писали, случайно?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Axel
сообщение Jul 12 2013, 07:30
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188



Цитата(msalov @ Jul 12 2013, 09:31) *
... добавить include-guard

... или "#pragma once".
Go to the top of the page
 
+Quote Post
flopix
сообщение Jul 12 2013, 09:42
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 21-06-12
Пользователь №: 72 429



Цитата(Сергей Борщ @ Jul 12 2013, 08:59) *
Потому что каждый файл *.c компилируется отдельно от других



Да в этом было мое недопонимание.
Пишу в Coocox (на основе eclipse)
Go to the top of the page
 
+Quote Post
ARV
сообщение Oct 16 2013, 06:58
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



что-то я тоже как-то туплю.
есть такое определение:
Код
#define MENU_CNT    sizeof(menu) / sizeof(menu_item_t)

теперь я хочу ЧИСЛОВУЮ константу MENU_CNT поиметь в виде СТРОКОВОЙ константы, то есть вместо, предположим, 12 получить "12".
как это делается? пробовал # MENU_CNT - так и получаю "MENU_CNT", что мне совсем ни к чему...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
XVR
сообщение Oct 16 2013, 09:27
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(ARV @ Oct 16 2013, 10:58) *
как это делается?
Никак. Поделить sizeof(menu) / sizeof(menu_item_t) может только сам компилятор, а препроцессор запускается до него, и никак с внутренними процессами в компиляторе не связан.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th June 2025 - 17:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01451 секунд с 7
ELECTRONIX ©2004-2016