![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| EnergoHokum |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 600 Регистрация: 10.11.2006 Где: Россия, Ставропол ь Репутация: нет Всего: 6 |
Такой вопрос: есть, к примеру, файлы first.cpp, first.h, second.cpp, second.h.
Из них собираются объектные файлы соответственно first.o и second.o, которые после слинковываются в одну библиотеку. В second.h объявлена переменная, которая используется как в first.cpp, так и в second.cpp. Соответственно, second.h включен и в first.cpp, и в second.cpp. При линковке компилятор ругается на то, что в обоих *.o файлах объявление этой переменной дублируется. Правильно ли будет задать ей модификатор static, или есть "более другие" методы решения этой проблемы? |
|||
|
||||
| MAKCim |
|
||||||||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
EnergoHokum,
в second.h переменная должна быть объявлена с модификатором extern а определена в одном из .cpp-файлов
неправильно, если переменная должна быть глобальной для всех модулей если ее определить как static, то в каждом модуле будет свой локальный экземпляр переменной
Это сообщение отредактировал(а) MAKCim - 6.12.2007, 10:12 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||||||||
|
|||||||||||
| EnergoHokum |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 600 Регистрация: 10.11.2006 Где: Россия, Ставропол ь Репутация: нет Всего: 6 |
Хм, когда переопределил с extern, пошла ругань вида: ...undefined reference to.... Эту переменную нужно инициализировать в соответствующем *.cpp, или всё равно где?
Это сообщение отредактировал(а) EnergoHokum - 6.12.2007, 10:15 |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
EnergoHokum,
я же пример написал специально
все равно, главное должно быть где-то определение (но не в .h-файле естественно) -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| EnergoHokum |
|
||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 600 Регистрация: 10.11.2006 Где: Россия, Ставропол ь Репутация: нет Всего: 6 |
В общем, упрощённо ситуация такая:
Действительно, при объявлении переменных со static для каждого .o-файла они получаются свои, но и с extern тоже ничего хорошего не выходит. |
||||||||||
|
|||||||||||
| t_gran |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 621 Регистрация: 13.11.2007 Где: г.Усть-Илимск Репутация: 1 Всего: 37 |
Предлагаю так:
-------------------- Я знаю, что ничего не знаю© Сократ ![]() |
|||
|
||||
| MAKCim |
|
||||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||||
|
|||||||
| EnergoHokum |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 600 Регистрация: 10.11.2006 Где: Россия, Ставропол ь Репутация: нет Всего: 6 |
Мне нужно, чтобы переменные оставались там, где они лежат сейчас, по контексту они так привязаны. Можно (наверное) вообще сгрести их все в один .h-файл, но это не решение. Это здесь два объектника, а в проекте их больше. Перетряхивать всю структуру проекта? Это практически невозможно.
Это сообщение отредактировал(а) EnergoHokum - 6.12.2007, 10:53 |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
ну что значит привязаны? разве сейчас что-то изменилось? абсолютно ничего, просто определение переменных я вынес в отдельный .cpp-файл чтобы не было нарушения правила одного определения при подключении .h-файла в разные .cpp-файлы по-другому здесь не сделаешь в .h-файле не должно быть не static-определений Это сообщение отредактировал(а) MAKCim - 6.12.2007, 10:56 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
MAKCim, а зачем
и оффтопный вопрос. где-то слышал, что static (не в функциях) делать не рекомендуется. почему, не подскажешь? |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
имхо, так наглядней
если речь о С++, то там есть анонимные пространства имен, которые заменяют static -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| EnergoHokum |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 600 Регистрация: 10.11.2006 Где: Россия, Ставропол ь Репутация: нет Всего: 6 |
Ви будете смеяться, но таки ничего не изменилось! Или это я уже туплю?
Да, действительно, туплю. Но всё равно как-то неизящно выходит. Счас поковыряюсь ещё, может, что и придумается... Это сообщение отредактировал(а) EnergoHokum - 6.12.2007, 11:08 |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
global.cpp создал? поместил туда определение символов? добавил в Makefile global.cpp и global.o -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
||||
|
||||
| Random13 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
А разве статик не должны быть тоже определены в срр файле ? В h файле только, вроде, объявление идет, а память должна выделятся в срр ? Как я понимаю, в одном файле h глобальная переменная должна быть объявлена без extern, этот файл должен быть подключен к срр, где ей отводится память, в остальных h файлах должно стоять extern. Разве только для static - extern бесполезно делать ее видимость все равно ограничивается файлом. Это сообщение отредактировал(а) Random13 - 6.12.2007, 11:34 |
|||
|
||||
| EnergoHokum |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 600 Регистрация: 10.11.2006 Где: Россия, Ставропол ь Репутация: нет Всего: 6 |
Да, порядок, завелось, пропустил в Makefile одно вхождение. Но некрасиво!!! Некрасиво. Нужно сделать лучше. Буду пробовать.
|
|||
|
||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
static-определение может быть в .h-файле например, если в каждом .cpp-файле, куда подключается .h-файл, должны быть локальные копии данных, которые определены как static в .h-файле Добавлено через 1 минуту и 11 секунд
это не некрасиво, а правильно -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| Random13 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Ну если в каждом cpp файле идет просто копия, то в h файле не определение, а объявление переменной, память таки ей выделяется в срр. И в каждом срр ее нужно будет определить как глобальную, и при желании инициализировать...Я так понимаю... Что, в общем, можно сделать и без этих хлопот с h файлом... Добавлено через 8 минут и 20 секунд Хотя тут опять же возникает вопрос, если я эту переменную в h файле использую, скажем в inline функции, а память выделил в нескольких срр файлах и хедэр файл ко всем к ним подключается, то какая переменная будет тогда использоваться в этой функции ? Это сообщение отредактировал(а) Random13 - 6.12.2007, 11:42 |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
зачем лишние телодвижения, если есть .h-файлы? пример кода можно? -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| Random13 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Для чего тут нужно объявление статической глобальной не совсем понятно, если в каждом срр ее нужно опять писать и инициализировать. Скорее всего для наглядности в хедер файле объявление - что мол такая переменная тут есть, обычно же каждому срр соответствует один хедер с объявлениями. Пример кода напишу, как освобожусь, я тут занят чуток - застрял на какой-то обидной плюхе не понятно в чем ошибка... Это сообщение отредактировал(а) Random13 - 6.12.2007, 15:52 |
|||
|
||||
| Random13 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
В общем в моем понимании хэдер файлы в проекте С++, в основном используют, как краткую ссылку на то, что же там есть в срр и для связи данного срр с остальным проектом.
Так, как область видимости статической переменной ограничена самим файлом срр, то о связи с проектом речь тут не идет, скорее для наглядности. А так объявление ее в хедэр ни на что не влияет - постирать эти объявления из h файлов и ничего не изменится... Это сообщение отредактировал(а) Random13 - 6.12.2007, 16:27 |
|||
|
||||
| zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
||||
|
||||
| bsa |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
|
||||
|
|||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| zkv |
|
||||||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
да пожалуйста, пример ниже в VC++8 работает. У Страуструпа есть обоснование, типа глобальные константные переменные не экспортируются
Это сообщение отредактировал(а) zkv - 6.12.2007, 21:59 |
||||||
|
|||||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
zkv,
в С не прокатит в С++ возможно (если уж Страуструп пишет -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
||||
|
||||
| SergeCpp |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 955 Регистрация: 8.8.2005 Где: At Home Репутация: 15 Всего: 124 |
Тут пример простой, но можно ведь и несколько const-переменных (объектов), которые могут вставляться в список, сравниваться посредством указателя (для объектов) и т.д. Использовать-то можно, конечно же, учитывая, что одна (логически) переменная превращается при таком использовании в несколько физических областей памяти |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
SergeCpp,
const-переменные на то и const-переменные, чтобы их использовать только по значению, которое подставляется компилятором в виде непосредственного операнда инструкций имхо, все остальные варианты использования ошибочны -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
MAKCim, ты хочешь сказать, что код:
|
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
bsa,
я про классы и прочие сложные типы не говорил -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Я имел в виду, что можно передавать по константной ссылке или указателю.
|
|||
|
||||
| archimed7592 |
|
||||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
MAKCim, я имею немного иное мнение о спектре применения const переменных. Даже примитивных типов. Если я не изменяю в ф-ции переменную, то я объявляю её const. Привычка. Зато через месяц такие исходники читать проще.
zkv, я точно не уверен, ибо Стандарт знаю не на зубок, но из того, что описано в п. 3.2(ODR) следует, что для констант(даже примитивных типов) никаких исключений в этом плане нет. Добавлено через 5 минут и 10 секунд Собственно говоря, студия нарушает стандарт, т.к. такой код:
Выводит на экран следующее:
Т.е. адреса у одной и той же переменной разные, что противоречит 3.2/3:
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||||
|
|||||||
| Random13 |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Но конст переменные - это по сути тот же дэфайн, где-то, кстати читал, что использования конст переменных предпочтительнее дэфайна, по возможности, правда уже не помню почему. Тут я подзабыл, и неправильно немного написал до этого. Вообще получается, что в h файлах глобальные переменные, кроме статических ни объявлять ни определять нельзя. По сути при компиляции тело h файла переписывается в срр файл на месте, где стоит инклюд, и поэтому если мы напишем в h файле, например int a;, и подключим его к main.cpp и a.cpp, то будет ошибка компоновки redifinition. Так как этот файл перепишется 2 раза и будет попытка создания 2-х глобальных переменных с одним именем. Так видимо и происходит при static, просто в этом случае в каждом срр файле создается своя копия переменной, как и в случпе с const, просто видать так как - это const - то компилятор забивает на эту ошибку. То есть глобальную переменную можно определить в срр файле, а в остальных файлах писать extern, можно и в h файле, но при этом подключить его можно только один раз к срр файлу, (понятно можно a.h подключить к b.h, и потом в b.cpp подключить a.h и b.h, так как в этом случае, если стоит #ifndef файл просто не подключится второй раз |
||||
|
|||||
| UnrealMan |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Ты упустил один маленький момент: это не одна и та же переменная
Добавлено через 2 минуты и 42 секунды
Объявлять-таки можно. Это сообщение отредактировал(а) UnrealMan - 8.12.2007, 18:57 |
||||||
|
|||||||
| Random13 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Всмысле как написать в h файле ? Ну если написать с extern - то да - можно. Это сообщение отредактировал(а) Random13 - 8.12.2007, 20:27 |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Да какая разница где? Впрочем, по твоим постам видно, что ты не понимаешь, зачем нужны h-файлы. А без extern это будет определение, а не просто объявление. Это сообщение отредактировал(а) UnrealMan - 8.12.2007, 21:07 |
|||
|
||||
| Random13 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
У меня у самого такое ощущение, что, чем больше знаю - тем меньше понимаю...
Это сообщение отредактировал(а) Random13 - 9.12.2007, 13:40 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |