![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| inside_pointer |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
Чем отличаются эти коды ?
Вообще может быть переменная extern неглобальной ? Она всегда используется только для связывания файлов, или может использоваться для чего-нибудь в одном файле ? |
||||
|
|||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
переменная extern неглобальной быть не может.
в одном файле extern переменная может ссылаться на переменную, описанную ниже:
твой код одинаков: при помощи extern ты не определяешь переменную, а только объявляешь, ссылаясь на некую глобальную i. |
|||
|
||||
| inside_pointer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
То есть extern может ссылаться на глобальную переменную описанную выше, а может ссылаться на глобальную переменную описанную ниже ? У меня в книжке написан такой код, когда глобальная переменная одна(ну или массивы там до main идут), а функции которые используют эти массивы принимают void значения, в теле каждой функции массивы проставляются в виде extern массивов без указания размеров и говорится, что размеры не указываются тогда, когда они уже объявлены где-то выше в коде. Это сообщение отредактировал(а) inside_pointer - 29.3.2008, 15:36 |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
может.
что касается массивов, то при определении надо указать размер, а при (extern) объявлении - необязательно. |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
при определение глобальной переменной компилятор выделяет место для нее
а при extern - компилятор предполагает, что место уже выделено где то (связывание произойдет при линковке) Это сообщение отредактировал(а) mes - 29.3.2008, 21:09 |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
в С и С++ это называется объявлением (declaration) и определением (definition) переменной.
|
|||
|
||||
| GSasha |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 77 Регистрация: 23.3.2008 Где: Ukraine Репутация: нет Всего: нет |
Привет всем!
На стадии компиляции все extern обьекты говорят компилятору "не ругайся, мол я полюбому где-то есть...", и тот просто оставляет пустое место под даный тип! Но на стадии сбора *.exe файла (линковки) эти пустые места должны заполниться реально существующими обьектами, и если компилятор был подвержен обману, то линкер наругает и выдаст матом - unresolved external symbol... |
|||
|
||||
| inside_pointer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
Глобальное пространство единое для всех файлов или разбито на части ?
Имеет ли смысл использовать extern для создания отдельного модуля ? Например есть файл, его считаем модулем, в нём определяем глобальную переменную, потом в этом файле(модуле) ссылаемся на неё через extern. Будет ли в таком случае эта глобальная переменная влиять на переменную с таким же именем, находящуюся в другом файле(другом модуле) ?
Это что означает, что будет выделена память для глобальной переменной, а потом ещё память для локальных будет выделяться ? Или же будет происходит обращение к участку памяти, который был выделен для глобальной переменной выше ? Мне показалось всё быстрее работает когда используются просто ссылки через extern(или быстрее компилируется). |
|||
|
||||
| vinter |
|
||||||||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
этого делать не надо, это бессмысленные действия
будет, глобальная видимость у всех связанных едениц трансляции одна.
шо?
единое
каких локальных? в данном случае у тебя глобальная переменная, для которой в определенном месте выделяется память. Выделяется она 1 раз. |
||||||||||
|
|||||||||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
inside_pointer, тут уже говорили, что extern просто говорит компилятору: "переменная уже где-то определена, компилируй - остальное не твоя забота". Компилятор в итоге генерирует код: "... а в этом месте нужна переменная xxx ...". Линкер получает этот код и объединяет с остальными объектными файлами. Если переменная xxx только в одном из них найдена (определена), то все будет собрано, если не будет найдена, то возникнет ошибка "undefined reference", если будет найдено более одной переменной, то тоже возникнет ошибка, так как непонятно, которую из них использовать.
|
|||
|
||||
| MAKCim |
|
||||||||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
гы
вопрос, что будет выведено? Это сообщение отредактировал(а) MAKCim - 30.3.2008, 13:02 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||||||||
|
|||||||||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
MAKCim, ну static тоже можно заюзать и ошибки не будет. Но речь ведь не об этом, правильно?
|
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
так в том-то вся и фишка, что если использовать static, то все будет детерминировано и результат будет 5 в этом же случае нет и и однозначно определенного результата -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
MAKCim, ну и зачем оно нужно?
|
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
а вопрос разве был в этом? я лишь хотел оспорить тезис
ps. хороший вопрос для теста, кстати -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Вопрос может быть и хороший, но я, например, о __attribute__((weak)) вообще впервые слышу. Более того, мне даже сходу не удалось найти описание того, что это такое и тем более, зачем это может быть нужно.
|
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
bsa,
в этом примере weak вообще не имеет никакого смысла это пример ради примера 1. ядро к примеру мы пишем модуль ядра и не знаем точно, экспортируется ли нужный нам символ, или нет в зависимости от этой информации, мы можем строить код по-разному если просто тупо использовать этот символ, то мы просто не сможем загрузить модуль, если символ не экспортируется решение такое
код загрузки модуля ядра сначала пытается найти идентификатор "do_debug" в таблице экспортируемых символов ядра если ничего не найдено, проверяется атрибут символа (из соответствующего элемента таблицы символов модуля) если атрибут WEAK не установлен, то возвращается ошибка и модуль не загружается иначе - значение символа (его адрес) устанавливается в 0 и callback __do_debug будет равен 0 в самом коде ядра на этапе инициализации проверяется __do_debug 2. glibc все malloc-хуки основаны на атрибуте WEAK см. man __malloc_hook если вкратце, он используется для возможности переопределения используемой динамической библиотекой функциональности например, в GLIBC определен WEAK символ __malloc_initialize_hook (в виде указателя на функцию) при инициализации аллокатора malloc(), идет вызов функции по адресу __malloc_initialize_hook по-умолчанию __malloc_initialize_hook содержит адрес дефолтной функции инициализации, которая инициализирует WEAK символ __malloc_hook, содержащий адрес функции, на которую передается управление после вызова malloc() мы можем переопределить __malloc_initialize_hook в своем коде и при инициализации аллокатора, соответствующая функция будет вызвана если бы у __malloc_initialize_hook не было атрибута WEAK, то на этапе динамической компоновки возникла бы ошибка двойного определения __malloc_initialize_hook (в коде программы, и в коде библиотеке) прямо можно в FAQ сей трактат Это сообщение отредактировал(а) MAKCim - 30.3.2008, 14:17 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| inside_pointer |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
В функции объявляются эти точки выхода на глобальные переменные, для чего они объявляются в функции? только для того чтобы если глобальные переменные определены ниже вызова этой функции или в другом файле относительно этой функции, функция могла их найти ?
Как она будет влиять на переменную в другом файле, если в другом файле не объявить наличие внешней переменной где-то, но использовать одноимённую ей там ? Будет выдана ошибка о недоступности глобальной переменной ? |
||||
|
|||||
| korian |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 8.3.2008 Где: Украина, Харьков Репутация: 3 Всего: 17 |
тут я фигню сказал
Это сообщение отредактировал(а) korian - 30.3.2008, 14:28 |
|||
|
||||
| korian |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 8.3.2008 Где: Украина, Харьков Репутация: 3 Всего: 17 |
хотя все-таки не фигню.
нормальный компилятор выдаст ошибку, при линковке такого кода (без __attribute__((weak)) - не знаю что оно дает) по поводу хорошести этого вопроса для теста... теста для определения знания gcc - да. только смысл в таком тесте? хотя варианты могут быть разные... но имху тестировать лучше знание языка, чем знание компилятора. тезис не оспорен в стандерте C++... а в стандарте конкретной реализации компилятора оспорить можно все что угодно. Это сообщение отредактировал(а) korian - 30.3.2008, 14:51 |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
korian,
к копилятору тут имеет отношение только синтаксис определения атрибута -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| korian |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 8.3.2008 Где: Украина, Харьков Репутация: 3 Всего: 17 |
||||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
нет, нельзя и вообще не понимаю, в чем проблема тут - будет 2 глобальных переменных - то есть ошибка линковки. и что с того? и при чем тут вообще extern? |
|||
|
||||
| vinter |
|
||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
да
можно использовать одноименную локальную переменную, тогда она скороет имя глабальной, и заменит ее.
да, если переменная не определена, но декларирована extern'ом |
||||
|
|||||
| inside_pointer |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
нет, я имел ввиду не это, я имел в виду, что переменную используем как глобальную(то есть просто к ней обращаемся)
Но видимо обращение к глобальной переменной без объявления внешней переменной - это то же самое что обращение к глобальной переменной с объявлением её как внешней переменной. По крайней мере в книжке у меня сложилось такое впечатление, потому что они говорят что объявления extern можно опускать если определения находятся выше обращений и это обычная практика - обращаться к глобальной переменной, не объявляя её как требует стандарт. |
||||
|
|||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
inside_pointer, проведи пару экспериментов
похоже ты совсем неверно понял, что такое глобальные переменные в разных модулях и слово extern |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
да, если определение находится в том же модуле. а если у тебя переменная определена в другом модуле, а ты хочешь юзать ее в этом? вот за этим и нужен extern. А вообще глобальные переменные это зло, старайся их избегать. |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
были уже топики на эту тему... тупо следовать стереотипам - вот это зло -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
MAKCim, я не говорю не юзай ГП никогда, я написал
|
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
ты сказал, что глобальные переменные - это зло к этому я и предрался -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| inside_pointer |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
Если я не объявлю её, она выдаст ошибку ?
С чего ты взял что я неправильно понял ? |
||||
|
|||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
из-за
и т.д. extern нужен только для того, чтобы 2 модуля использовали 1 переменную Вся проблема в том, что компилер компилирует каждый cpp отдельно. Потому и придумали такой маневр с extern Если бы он компилил сразу всю прогу (весь проект), то и ключевого слова extern не было бы |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| inside_pointer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
Не, не только, ещё если определение глобальной переменной стоит ниже обращения к ней в одном модуле. Ладно, vinter, спасибо, просвятил меня конкретно |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
inside_pointer, настоятельно рекомендую тебе почитать пункт стандарта 3.5 Program and linkage. А форумчанам ты особо не доверяй - в вопросах касательно linkage они разбираются не намного лучше тебя.
|
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
для этого используются прототипы -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| inside_pointer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
Я писал вот такую
Ошибок не выдал |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
да ты прав, забыл правда вероятность, что тебе придется эту возможность использовать практически равна 0, если прогу писать буш нормально (то есть все инклуды вверху cpp-шки и так далее) |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
||||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
поскольку "прототип" - это объявление, а объявление переменной - это с ключевым словом extern, то extern int i; - это прототип переменной
|
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Не надо фантазий. Есть лишь понятие "function prototype". Которое есть форма вызова функции. Которая может являться частью объявления функции.
extern int i; - это объявление переменной Если я неправ, покажите где про это в стандарте. |
|||
|
||||
| marcusmae |
|
||||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
Ребят, если можно, у меня вопрос по теме :
Компилятор - MVC++ 9.0 (2008) Я собрал несколько библиотек и прилинковал их к одному exe-шнику. Как импортировать/экспортировать функции и классы - сам знаю и другим объяснял уж никак не меньше 100 раз Правильно ли, что в библиотеке, которая должна содержать сами символы, я даю определения, например :
- iostring - это такая глобальная книга жалоб и предложений, в которую каждый класс в любой из библиотек должен иметь возможность излить свою проблему. Следовательно, во всех других библиотеках я должен дать описания, как extern.
Правильно? -------------------- ἀπὸ μηχανῆς θεός |
||||
|
|||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Нет, неправильно. Нельзя задавать размер статического массива переменной.
Попробуй extern iostring[] или сделай MAXIOSTRINGLENGTH макросом (#define MAXIOSTRINGLENGTH 1024), что более соответствует способу именования (заглавными буквами принято называть макросы). |
|||
|
||||
| marcusmae |
|
|||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
-------------------- ἀπὸ μηχανῆς θεός |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Можно поместить
в заголовочный файл, поставляемый к библиотеке. |
|||
|
||||
| inside_pointer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 9.3.2008 Репутация: 5 Всего: 12 |
Не, вот допустим функции находятся не в конце а в начале, или откуда там она может вызываться в том же файле, тут она объявлена в функции main а может быть объявлена в других функциях, которые могут идти до main. Таким образом она будет стоять после них, быть в том же файле и, несмотря на то, что она определена ниже своего объявления в каждой из функций, исправно работать при этом, я уже всё выяснил сколько можно мусолить |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |