![]() |
|
Модераторы: bsa |
![]()
|
|
| Alchimik |
|
||||||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
Интерес по большей части теоретический. Есть два фала .cpp, оба подключают head.h
Вот содержимое подключаемого файла:
Возникает ошибка множественного определение переменной x. Вопрос - почему возникает ошибка? По моему разумению, раз int x = 5; находится в блоке ifndef ... endif, то и определяться переменная x должна только один раз, а при повторном подключении заголовочного файла блок ifndef ... endif должен игногрироваться, как будто его там и нет. |
||||||
|
|||||||
| KaraKum |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 640 Регистрация: 3.12.2007 Репутация: нет Всего: 1 |
Объявление переменной "x" нужно выделить в "info.cpp" и подключать к проекту так же как и любые другие .cpp-файлы. А там где эта переменная используется нужно писать перед началом её использования:
Добавлено @ 19:44 В этом примере переменная объявляется 2 раза потому что подключается загаловочный файл 2 раза. По одному разу в каждом .cpp-файле. Это сообщение отредактировал(а) KaraKum - 18.1.2011, 19:45 |
|||
|
||||
| Alchimik |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
Я согласен, заголовочный файл подключается два раза, но раз обявление переменной стоит в блоке ifndef ... endif, при втором подключении заголовочного файла разве не должно содержимое этого блока игнорироваться? ps: наверно вы имели в виду "определяется 2 раза" Это сообщение отредактировал(а) Alchimik - 18.1.2011, 19:54 |
|||
|
||||
| Фантом |
|
|||
![]() Вы это прекратите! ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1516 Регистрация: 23.3.2008 Репутация: 4 Всего: 49 |
"Препроцессор" на то и "пре", что он работает до компилятора, а не после. При попытке все это собрать происходят две независимых компиляции, соответственно, и препроцессор отрабатывает два раза независимо друг от друга. А ошибку множественного определения находит линковщик, к моменту запуска которого вся компиляция уже закончена. |
|||
|
||||
| Alchimik |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
Я себе представлял процесс так: сначала препроцессор обрабатывает первый файл .cpp, доходит до строки #include "head.h", оббрабатывает файл head.h и результат вставляет вместо #include "head.h". Во время обработки head.h препроцессор встречает строку #ifndef HEAD_H, переменная HEAD_H, такчто она определяется (#define HEAD_H). Получается вместо #include "head.h" препроцессор вставляет в первый файл строку int x = 5; Затем препроцессор обрабатывает второй .cpp файл, дойдя до #include "head.h" он снова обрабатывает файл head.h, но в этот раз переменная HEAD_H определена, поэтому всё что находится между #ifndef HEAD_H и #endif пропускается. Т.е. вместо #include "head.h" препроцессор вставляет пустую строку. Но если так рассуждать, никакого множестваенного определения переменной нет. Вы говорите что "препроцессор отрабатывает два раза независимо друг от друга", то есть при обработке второго файла он уже "не помнит" что переменная HEAD_H была определена во время обработки первого файла? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
каждый юнит (.cpp) транслируется (компилируется) отдельно, а потом уже выходные файлы собираются (линкуются) в конечный (.exe)..
|
|||
|
||||
| Alchimik |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
KaraKum, Фантом, mes, спасибо за помощь |
|||
|
||||
| БелАмор |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 209 Регистрация: 10.6.2010 Где: Россия Репутация: нет Всего: 17 |
||||
|
||||
| Alchimik |
|
||||||||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
Можно вполне обойтись и без .h файла. Например так (два .cpp файла):
|
||||||||
|
|||||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| Alchimik |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
Область видимости переменной объявленной со спецификатором const ограничена файлом. Это свойство позволяет определять переменные со спецификатором const в заголовочных файлах, при этом для каждого файла, подключающего данный заголовочный файл будет создана собственная копия константы. Или надо написать extern const int x = 5; Это сообщение отредактировал(а) Alchimik - 18.1.2011, 22:32 |
|||
|
||||
| БелАмор |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 209 Регистрация: 10.6.2010 Где: Россия Репутация: нет Всего: 17 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| Alchimik |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
да.. но глобальные константы из примера не линкуются по другому поводу.. Добавлено через 59 секунд видимость что у константной, что у обычной переменной одна и та же... |
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |