Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> что такое #ifndef 
:(
    Опции темы
CROC
Дата 20.1.2007, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 16.10.2005
Где: Perm

Репутация: нет
Всего: нет



для чего:
Код

#ifndef _SPI_LIB_H_
#define _SPI_LIB_H_

а так же 
#ifdef
#endif

в моем простеньком учебничке такого не нашел smile

Это сообщение отредактировал(а) CROC - 20.1.2007, 13:29
PM MAIL ICQ   Вверх
Rodman
Дата 20.1.2007, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


CIO
****


Профиль
Группа: Участник
Сообщений: 6144
Регистрация: 7.5.2006
Где: Ukraine ⇛ Kyiv ci ty

Репутация: нет
Всего: 122



Встретив одну из первых двух директив, препроцессор проверяет, определено ли символическое_имя, и, в случае с #ifdef отдает компилятору последующие строки, только если оно определено, в случае же с #ifndef — наоборот, только если не определено. Так он поступает со всеми строками до тех пор, пока не встретится #else или #endif. Собственно, #ifdef и #ifndef — это сокращения от аглийских фраз if defined («если определено») и if not defined («если не определено»). Инструкция #else, как и ее аналог в упомянутом операторе ветвления, переводится как «иначе» и действует аналогично (в частности, директива эта тоже не обязательна). Ну а #endif в переводе означает «конец «если»». Кстати, блоки директив #if...#else...#endif, как и их операторные тезки, могут быть вложенными — таким образом, на определенность-неопределенность директив тоже можно налагать сколь угодно сложные условия.

источник
PM MAIL WWW Skype GTalk YIM MSN   Вверх
skyboy
Дата 20.1.2007, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: нет
Всего: 260



CROC, одно из применений - кроссплатформенный компилинг. представь, что у тебя код отличается 5 десятками строк под два разных контроллера. как будешь делать? вести параллельно две копии практически одинакового кода? будет головная боль с синхронизацией... А так: делаешь, например:
Код

#define MK1560

и потом в коде делаешь вилку не на if, которые будут компилироваться и влиять на итоговый размер, а #ifndef:
Код

#ifdef MK1560
int i;
#endif
#ifdef MK1565
char i;
#endif

В конечном итоге для компилирования под некую МК1565 надо будет только сменить строку "#define MK1560" на "#define MK1565" и приложение будет скомилировано уже под МК1565. И при любом режиме компилироваться будет только то, что необходимо. В исполняемом коде - ни одного линего байта.
Однако, при таком подходе надо следить, чтоб не было противоречивых объявлений: в приведенном примере
Код

#define MK1560
...
#define MK1565

могут сделать программу полностью неработоспособной.
Второй вариант использования: для дебагинга. Сделать так, что некоторые строки будут компилироваться, только если определение есть. Убрал определение - код дебага не компилируется даже. Удобно.
Третий вариант, который видел, но сам не использовал - предотвращение #include'инга модуля несколько раз: сделать так в самом модуле "#define my_module_1", а так в программе:
Код

#ifdef my_module_1
#include <mymod>
#endif

И модуль будет вкомпилен только разово. Правда, об этом слышал на лекции по BС++ 3.0, наверняка современные компиляторы предотвращают такую ситуацию...
PM MAIL   Вверх
CROC
Дата 20.1.2007, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 16.10.2005
Где: Perm

Репутация: нет
Всего: нет



Всем большое спасибо!!!
как я понял эта логика нужна для компиляции и отладки, а не для работы самой программы
PM MAIL ICQ   Вверх
PILOT
Дата 20.1.2007, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


производство
****


Профиль
Группа: Модератор
Сообщений: 2724
Регистрация: 4.4.2002
Где: москва

Репутация: 20
Всего: 54



Ребята, молодцы, очень хорошо объяснили все!

СУВ.


--------------------
тут могла быть Ваша реклама...
PM MAIL WWW ICQ   Вверх
Кристиан
Дата 3.2.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 2.2.2007
Где: АР Крым. Севастоп оль.

Репутация: нет
Всего: нет



Такая комбинация нужна еще для того, чтобы не было повторных включений заголовочных файлов.
PM MAIL ICQ   Вверх
EvilsInterrupt
Дата 26.7.2009, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



недавно задал массив строк:

Код

typedef enum ERROR_IO {
//
//
// 
  EIO_COUNT
} *PERROR_IO ;

char * error_io_messages[EIO_COUNT] = 
{
 "Stream open failed",
///
///
///
};


и все это задекларировал в инклуде exceptions_io.h , который включал в другие *.cpp файлы помимо exception_io.cpp и был поражен тем, что находилось два массива error_io_messages. Только потом меня  любезный Lazin просвятил, что в инклудах,который включаются в другие файлы не следуют объявлять реальные переменные ! Т.е вывод: инклуды это декларация структур, классов, енумы и т.д. и т.п. 
PM MAIL WWW ICQ Jabber   Вверх
UniBomb
Дата 27.7.2009, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 97



EvilsInterrupt, вообще непонятно к чему ты апнул эту тему, но:

Цитата(EvilsInterrupt @  26.7.2009,  10:03 Найти цитируемый пост)
был поражен тем, что находилось два массива error_io_messages

Что бы этого избежать нужно использовать "стражей повторного включения". Т.е. что то типа такого:


Код

#ifndef _exceptions_io_h_
#define _exceptions_io_h_

typedef enum ERROR_IO {
//
//
// 
  EIO_COUNT
} *PERROR_IO ;

char * error_io_messages[EIO_COUNT] = 
{
 "Stream open failed",
///
///
///
};

#endif

PM MAIL ICQ Skype   Вверх
xvr
Дата 27.7.2009, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(UniBomb @ 27.7.2009,  08:27)
EvilsInterrupt, вообще непонятно к чему ты апнул эту тему, но:

Цитата(EvilsInterrupt @  26.7.2009,  10:03 Найти цитируемый пост)
был поражен тем, что находилось два массива error_io_messages

Что бы этого избежать нужно использовать "стражей повторного включения". Т.е. что то типа такого:

В данном случае это не поможет - вот это
Цитата

Код

...
char * error_io_messages[EIO_COUNT] = 
...

создаст по массиву error_io_messages в каждой единице трансляции, что приведет к слому на этапе линковки (о чем EvilsInterrupt и написал)


PM MAIL   Вверх
UniBomb
Дата 27.7.2009, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 97



Цитата(xvr @  27.7.2009,  13:52 Найти цитируемый пост)
В данном случае это не поможет

Почему? Ведь компилятор при повторном включении эти строки по идее просто пропустит, соответственно это файл будёт включон в проект в единичном экземпляре...
PM MAIL ICQ Skype   Вверх
xvr
Дата 27.7.2009, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(UniBomb @ 27.7.2009,  15:12)
Цитата(xvr @  27.7.2009,  13:52 Найти цитируемый пост)
В данном случае это не поможет

Почему? Ведь компилятор при повторном включении эти строки по идее просто пропустит, соответственно это файл будёт включон в проект в единичном экземпляре...

Повторного включения не будет, файл будет включен ровно 1 раз В КАЖДОЙ единице компиляции. А так как в нем error_io_messages не extern описание а именно определение переменной, то она появится в каждой единице компиляции, куда был включен исходный заголовочный файл


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.0527 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.