Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|||||||||||||||||||||||||||||||
1 | |||||||||||||||||||||||||||||||
Раздельная компиляция. Связывание const-переменных07.09.2017, 13:34. Показов 3646. Ответов 70
Метки нет (Все метки)
Не совсем понимаю процесс раздельной компиляции, или то как работает связывание const-переменных. Имеется три файла:
const_test.h
const_test.cpp
general.cpp
Собственно, почему это не вызывает ошибку компиляции? ( Компилировал в VS 2013 ) Разве не должен был произойти конфликт имен, когда в файл "const_test.cpp" включился файл "const_test.h"? Ведь, как я понимаю, extern const int var; -- это отличная переменная от const int var = 10; . Теперь немного изменим код:const_test.h
const_test.cpp
general.cpp
Это уже ошибка. И это, по-моему нормально ( а по законам C++ нет? ), ведь инструкция extern int var; 1) порождает конфликт имен, 2) ссылается на несуществующую переменную ( ведь ни в одной единице трансляции не была объявлена внешняя int переменная с именем var ). В коде изменилось ( опять же таки, по моему мнению ) только то, что переменная var перестала быть const .P.S.: Знаю, что не умею доступно объяснять, но у здешних жителей форума, как показывает практика, хорошо развиты телепатические способности, проблем возникнуть не должно
1
|
07.09.2017, 13:34 | |
Ответы с готовыми решениями:
70
Раздельная компиляция Раздельная компиляция раздельная компиляция Раздельная компиляция |
Любитель чаепитий
|
|
07.09.2017, 14:09 | 3 |
если оно в хедере объявлено, как
extern , то с чего оно вдруг связывание станет внутренним?а вот тут уже внутреннее связывание, в итоге ошибка компиляции, т.к. var нигде не определяется, но есть попытка использования объявленной переменной.Добавлено через 2 минуты в догонку: https://habrahabr.ru/post/150327/
1
|
672 / 475 / 215
Регистрация: 06.09.2013
Сообщений: 1,306
|
|
07.09.2017, 14:23 | 5 |
static появилось, а это внутреннее связывание, убрать его и не будет ошибки, разве не так?
1
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|
07.09.2017, 14:31 [ТС] | 6 |
GbaLog-,
Сообщение от GbaLog-
const int var = ?; , == static const int var = ?; .
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|||||||||||
07.09.2017, 14:32 | 7 | ||||||||||
нет не только.
и дело вовсе не в квалификаторе const во втором случае переменная объявляется как статическая. это значит, что область её видимости принудительно ограничивается одной ед. трансляции. а значит инструкция: extern int var уже не имеет к ней никакого отношения. поэтому, для соседней ед. трансляции глобальная переменная по прежнему остается объявленной, но неопределенной. а в первом случае все как обычно:
1
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
07.09.2017, 14:37 | 9 |
0
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
||||||
07.09.2017, 14:48 [ТС] | 11 | |||||
hoggy,
Сообщение от hoggy
const , объявленная вне функции/класса/другого блока, по умолчанию имеет внутреннее связывание.
Я, собственно, из-за этого и задал вопрос. Книга написана на основе C++11. Может, в новом стандарте, все по-другому? Это я сейчас не оспариваю, а просто уточняю.
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
07.09.2017, 15:10 | 12 |
см #7
ключевые слова: "объявленная" и "по умолчанию" в вашем случае: extern const int var; - это явное (больше уже никаких "умолчаний")объявление переменной с внешним связыванием. в то время как последующая за ней запись: const int var = 10; - это уже определение переменной объявленной ранее как с внешним связыванием. постречав её, компилятор вспоминает, что недавеча видел её объявление, и понимает, что вот конкретно для неё связывание должно быть внешним.
2
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|||||||||||
07.09.2017, 15:22 [ТС] | 13 | ||||||||||
hoggy, тогда какая разница между:
0
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|
07.09.2017, 15:29 [ТС] | 15 |
hoggy,
P.S.: Просто в книге сказано, что применение extern к определению const-переменной, дает ей внешнее связывание ( по умолчанию связывание внутрннее ).Применение extern к объявлению const-переменной, говорит компилятору, что где-то есть определение этой переменной ( в общем, как обычно это бывает ).
0
|
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
|
|||||||||||
07.09.2017, 15:41 | 16 | ||||||||||
что бы понять, удаляем хедер и оставляем два .cpp
const то тут и во втором файле надо явно указать extern , так как:
1
|
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
|
|
07.09.2017, 15:59 | 17 |
const это не переменная а константа, она должна инициализироваться при объявлении.
Константа в отличии от переменной не имеет адреса. Ее значение вшивается непосредственно в кота, при этом если в выражении имеются другие константы, константная часть вычисляется на этапе компиляции. Соответсвенно ни о каком связывании констант при раздельной компиляции речи быть просто не может. Константа просто объявляется и инициализируется в хидере.
1
|
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
|
|
07.09.2017, 16:21 | 18 |
Ну вот с квалификатором const константы и объявляются.
Добавлено через 1 минуту Ее нельзя не определить. Константа должна быть определена при объявлении.
1
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|
07.09.2017, 16:37 [ТС] | 19 |
Operok, да, я это понимаю. Сейчас попробую в очередной раз разъяснить ситуацию, чтобы вы поняли, чего я хочу.
Я понимаю, что определенная вне всех блоков переменная, по умолчанию имеет внешнее связывание. Я понимаю, что нужно использовать спецификатор extern в объявлении той самой переменной, чтобы использовать ее в другой единице трансляции.Я понимаю, что объявленная вне всех блоков переменная со спецификатором static , имеет внутреннее связывание.Также, что для меня стало новостью, переменная, определенная вне всех блоков с квалификатором const , по умолчанию имеет внутреннее связывание.Переменная, определенная вне всех блоков с квалификатором const и спецификатором extern , имеет внешнее связывание. ( Если объявить ее, а не определить, это будет трактоваться как ссылка ( не та, которая & ) на переменную в другой единице трансляции )Собственно, исходя из этих утверждений, const int var = 10 == static const int var = 10 . Инструкция extern const int var должна искать следующее определение: extern const int var = 10 , а не const int var = 10 ( ибо здесь внутреннее связывание ).Исходя из слов hoggy, я рассуждаю неверно. Поправьте меня, где ошибаюсь. Добавлено через 2 минуты Fulcrum_013,
Сообщение от Fulcrum_013
const .Не по теме: Дайте интернета, иначе я сломаю стол.
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||||||
07.09.2017, 17:28 | 20 | |||||
никакой.
если не считать, что в первом случае ключевое слово extern для определения переменной является избыточным. технически - да. объявить такие переменные можно. а вот использовать - не получится. компилятор пофиксит неоднозначность:
это избыточно. она итак будет с внешним связыванием, если была таковой объявлена. Добавлено через 4 минуты вам стоит подучить с++
1
|
07.09.2017, 17:28 | |
07.09.2017, 17:28 | |
Помогаю со студенческими работами здесь
20
Шаблоны и раздельная компиляция Раздельная компиляция файлов Раздельная компиляция и шаблоны Раздельная компиляция и шаблоны Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |