![]() |
|
Модераторы: 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 секунд видимость что у константной, что у обычной переменной одна и та же... |
|||
|
||||
| Alchimik |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
Цитата из С++ Primer. Липпман, 80 стр. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ну и где тут сказано, что у них иная область видимости ? |
|||
|
||||
| Alchimik |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
Я может что то путаю в терминалогии, но по мойму переменная без const объявленная в гловальной области видимости принадлежит глобальной области видимости, а переменная с const объявленная в глоальной области видимости ей не принадлежит, так как её облать видимости ограничена файлом. Или же надо понимать так: они обе принадлежат глобальной области видимости, но константа при этом локальна для файла. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ага близко.. области видимости принадлежит объявление, но не определение.. а локально (т.е имеет внутренее связывание) как раз определение.. в общем вам сюда http://www.cyberguru.ru/programming/cpp/cp...up2-page52.html P.S. что считается файлом в вышеприведенном контексте ? Добавлено через 33 секунды (если конечно не надо своими вопросами |
|||
|
||||
| Alchimik |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 1.12.2009 Репутация: нет Всего: 0 |
Помойму под "файлом" подразумевается просто файл, в котором объявлена переменная Нет конечно, спасибо вам за помощь и за то что указываете мне на мои ошибки. Хоть и учусь на факультете кибернетики, а изучать программирование проходится самому, по книгам. Поэтому ваши указания на неправильно понятые мною места особенно полезны для меня. Спасибо вам |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
под файлом подразумевается единица трансляции - т.е. .cpp файл со всеми включениями.. |
|||
|
||||
![]()
|
| Правила форума "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. |