Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> переменные extern 
V
    Опции темы
inside_pointer
Дата 29.3.2008, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Чем отличаются эти коды ?
Код

int i;

int main()
{
    extern int i;
    
    i = 0;
}


Код

int i;

int main()
{
    i = 0;
}


Вообще может быть переменная extern неглобальной ?
Она всегда используется только для связывания файлов, или может использоваться для чего-нибудь в одном файле ?
PM MAIL   Вверх
baldina
Дата 29.3.2008, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



переменная extern неглобальной быть не может.
в одном файле extern переменная может ссылаться на переменную, описанную ниже:
Код

extern int i;
...
++i;
...
int i;

твой код одинаков: при помощи extern ты не определяешь переменную, а только объявляешь, ссылаясь на некую глобальную i.
PM MAIL   Вверх
inside_pointer
Дата 29.3.2008, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Цитата(baldina)

в одном файле extern переменная может ссылаться на переменную, описанную ниже:

То есть extern может ссылаться на глобальную переменную описанную выше, а может ссылаться на глобальную переменную описанную ниже ?

У меня в книжке написан такой код, когда глобальная переменная одна(ну или массивы там до main идут), а функции которые используют эти массивы принимают void значения, в теле каждой функции массивы проставляются в виде extern массивов без указания размеров и говорится, что размеры не указываются тогда, когда они уже объявлены где-то выше в коде.

Это сообщение отредактировал(а) inside_pointer - 29.3.2008, 15:36
PM MAIL   Вверх
baldina
Дата 29.3.2008, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



может.
что касается массивов, то при определении надо указать размер, а при (extern) объявлении - необязательно.
PM MAIL   Вверх
vinter
Дата 29.3.2008, 16:39 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(inside_pointer @  29.3.2008,  16:35 Найти цитируемый пост)
То есть extern может ссылаться на глобальную переменную описанную выше, а может ссылаться на глобальную переменную описанную ниже ?

extern говорит что "где-то в глобальной пр-ве есть переменная с таким именем."


--------------------
Мой блог
PM MAIL WWW   Вверх
mes
Дата 29.3.2008, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



при определение глобальной переменной компилятор выделяет место для нее
а при extern - компилятор предполагает,  что  место уже выделено где то (связывание произойдет при линковке)

Это сообщение отредактировал(а) mes - 29.3.2008, 21:09


--------------------
PM MAIL WWW   Вверх
baldina
Дата 29.3.2008, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



в С и С++ это называется объявлением (declaration) и определением (definition) переменной.
PM MAIL   Вверх
GSasha
Дата 29.3.2008, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 23.3.2008
Где: Ukraine

Репутация: нет
Всего: нет



Привет всем!
На стадии компиляции все extern обьекты говорят компилятору "не ругайся, мол я полюбому где-то есть...", и тот просто оставляет пустое место под даный тип!
Но на стадии сбора *.exe файла (линковки) эти пустые места должны заполниться реально существующими обьектами, и если компилятор был подвержен обману, то 
линкер наругает и выдаст матом - unresolved external symbol... smile 
PM MAIL ICQ   Вверх
inside_pointer
Дата 30.3.2008, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Глобальное пространство единое для всех файлов или разбито на части ?

Имеет ли смысл использовать extern для создания отдельного модуля ?

Например есть файл, его считаем модулем, в нём определяем глобальную переменную, потом в этом файле(модуле) ссылаемся на неё через extern.
Будет ли в таком случае эта глобальная переменная влиять на переменную с таким же именем, находящуюся в другом файле(другом модуле) ?

Цитата(GSasha)

Но на стадии сбора *.exe файла (линковки) эти пустые места должны заполниться реально существующими обьектами

Это что означает, что будет выделена память для глобальной переменной, а потом ещё память для локальных будет выделяться ?
Или же будет происходит обращение к участку памяти, который был выделен для глобальной переменной выше ?

Мне показалось всё быстрее работает когда используются просто ссылки через extern(или быстрее компилируется).
PM MAIL   Вверх
vinter
Дата 30.3.2008, 08:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(inside_pointer @  30.3.2008,  02:57 Найти цитируемый пост)
Например есть файл, его считаем модулем, в нём определяем глобальную переменную, потом в этом файле(модуле) ссылаемся на неё через extern.

этого делать не надо, это бессмысленные действия

Цитата(inside_pointer @  30.3.2008,  02:57 Найти цитируемый пост)
Будет ли в таком случае эта глобальная переменная влиять на переменную с таким же именем, находящуюся в другом файле(другом модуле) ?

будет, глобальная видимость у всех связанных едениц трансляции одна.

Цитата(inside_pointer @  30.3.2008,  02:57 Найти цитируемый пост)
Имеет ли смысл использовать extern для создания отдельного модуля ?

шо?
Цитата(inside_pointer @  30.3.2008,  02:57 Найти цитируемый пост)
Глобальное пространство единое для всех файлов или разбито на части ?

единое
Цитата(inside_pointer @  30.3.2008,  02:57 Найти цитируемый пост)
Это что означает, что будет выделена память для глобальной переменной, а потом ещё память для локальных будет выделяться ?

каких локальных? в данном случае у тебя глобальная переменная, для которой в определенном месте выделяется память. Выделяется она 1 раз.


--------------------
Мой блог
PM MAIL WWW   Вверх
bsa
Дата 30.3.2008, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



inside_pointer, тут уже говорили, что extern просто говорит компилятору: "переменная уже где-то определена, компилируй - остальное не твоя забота". Компилятор в итоге генерирует код: "... а в этом месте нужна переменная xxx ...". Линкер получает этот код и объединяет с остальными объектными файлами. Если переменная xxx только в одном из них найдена (определена), то все будет собрано, если не будет найдена, то возникнет ошибка "undefined reference", если будет найдено более одной переменной, то тоже возникнет ошибка, так как непонятно, которую из них использовать.
PM   Вверх
MAKCim
Дата 30.3.2008, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(bsa @  30.3.2008,  11:36 Найти цитируемый пост)
если будет найдено более одной переменной, то тоже возникнет ошибка, так как непонятно, которую из них использовать. 

гы
Код

/* a.c */

__attribute__((weak))
int a = 2;

int get1() {
    return a;
}

Код

/* b.c */

__attribute__((weak))
int a = 3;

int get2() {
    return a;
}

Код

/* main.c */
#include <stdio.h>

extern int get1();
extern int get2();

int main() {
    printf("%d\n", get1() + get2());
    return 0;
}

Код

# gcc a.c b.c main.c -o main
# ./main

вопрос, что будет выведено?  smile 


Это сообщение отредактировал(а) MAKCim - 30.3.2008, 13:02


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 30.3.2008, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



MAKCim, ну static тоже можно заюзать и ошибки не будет. Но речь ведь не об этом, правильно?  smile 
PM   Вверх
MAKCim
Дата 30.3.2008, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(bsa @  30.3.2008,  13:06 Найти цитируемый пост)
ну static тоже можно заюзать и ошибки не будет. Но речь ведь не об этом, правильно?

так в том-то вся и фишка, что если использовать static, то все будет детерминировано и результат будет 5
в этом же случае нет и 
Цитата(bsa @  30.3.2008,  11:36 Найти цитируемый пост)
undefined reference

и однозначно определенного результата  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 30.3.2008, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



MAKCim, ну и зачем оно нужно?  smile 
PM   Вверх
MAKCim
Дата 30.3.2008, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(bsa @  30.3.2008,  13:25 Найти цитируемый пост)
MAKCim, ну и зачем оно нужно? 

а вопрос разве был в этом?  smile 
я лишь хотел оспорить тезис
Цитата(bsa @  30.3.2008,  11:36 Найти цитируемый пост)
если будет найдено более одной переменной, то тоже возникнет ошибка, так как непонятно, которую из них использовать. 


ps. хороший вопрос для теста, кстати


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 30.3.2008, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Вопрос может быть и хороший, но я, например, о __attribute__((weak)) вообще впервые слышу. Более того, мне даже сходу не удалось найти описание того, что это такое и тем более, зачем это может быть нужно.
PM   Вверх
MAKCim
Дата 30.3.2008, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



bsa, 
в этом примере weak вообще не имеет никакого смысла
это пример ради примера
Цитата(bsa @  30.3.2008,  13:32 Найти цитируемый пост)
зачем это может быть нужно. 

1. ядро
к примеру мы пишем модуль ядра и не знаем точно, экспортируется ли нужный нам символ, или нет
в зависимости от этой информации, мы можем строить код по-разному
если просто тупо использовать этот символ, то мы просто не сможем загрузить модуль, если символ не экспортируется
решение такое
Код

__attribute__((weak)) extern void do_debug(struct pt_regs*, unsigned long);
static void (*__do_debug)(struct pt_regs*, unsigned long) = &do_debug;

код загрузки модуля ядра сначала пытается найти идентификатор "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 сей трактат  smile 

Это сообщение отредактировал(а) MAKCim - 30.3.2008, 14:17


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
inside_pointer
Дата 30.3.2008, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Цитата(vinter)

каких локальных? в данном случае у тебя глобальная переменная, для которой в определенном месте выделяется память. Выделяется она 1 раз.

В функции объявляются эти точки выхода на глобальные переменные, для чего они объявляются в функции? только для того чтобы если глобальные переменные определены ниже вызова этой функции или в другом файле относительно этой функции, функция могла их найти ?

Цитата(vinter)

будет, глобальная видимость у всех связанных едениц трансляции одна.

Как она будет влиять на переменную в другом файле, если в другом файле не объявить наличие внешней переменной где-то, но использовать одноимённую ей там ?
Будет выдана ошибка о недоступности глобальной переменной ?


PM MAIL   Вверх
korian
Дата 30.3.2008, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



тут я фигню сказал

Это сообщение отредактировал(а) korian - 30.3.2008, 14:28
PM   Вверх
korian
Дата 30.3.2008, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



хотя все-таки не фигню.
Цитата(MAKCim @  30.3.2008,  12:01 Найти цитируемый пост)
вопрос, что будет выведено?

нормальный компилятор выдаст ошибку, при линковке такого кода (без __attribute__((weak)) - не знаю что оно дает)

Цитата(MAKCim @  30.3.2008,  12:27 Найти цитируемый пост)
ps. хороший вопрос для теста, кстати 

по поводу хорошести этого вопроса для теста...
теста для определения знания gcc - да.
только смысл в таком тесте? хотя варианты могут быть разные...
но имху тестировать лучше знание языка, чем знание компилятора.

Цитата(MAKCim @  30.3.2008,  12:27 Найти цитируемый пост)
я лишь хотел оспорить тезис

тезис не оспорен в стандерте C++...
а в стандарте конкретной реализации компилятора оспорить можно все что угодно.


Это сообщение отредактировал(а) korian - 30.3.2008, 14:51
PM   Вверх
MAKCim
Дата 30.3.2008, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



korian, 
к копилятору тут имеет отношение только 
синтаксис определения атрибута  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
korian
Дата 30.3.2008, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(MAKCim @  30.3.2008,  19:08 Найти цитируемый пост)
korian, 
к копилятору тут имеет отношение только 
синтаксис определения атрибута  

чего-то я наверно не понимаю...
такую констркцию можно записать средствами C++?
PM   Вверх
Alek86
Дата 31.3.2008, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(korian @  30.3.2008,  23:17 Найти цитируемый пост)
такую констркцию можно записать средствами C++?

нет, нельзя

и вообще не понимаю, в чем проблема тут - будет 2 глобальных переменных - то есть ошибка линковки. и что с того?
и при чем тут вообще extern?


--------------------
user posted image    user posted image
PM MAIL   Вверх
vinter
Дата 31.3.2008, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(inside_pointer @  30.3.2008,  15:20 Найти цитируемый пост)
В функции объявляются эти точки выхода на глобальные переменные, для чего они объявляются в функции? только для того чтобы если глобальные переменные определены ниже вызова этой функции или в другом файле относительно этой функции, функция могла их найти ?

да
Цитата(inside_pointer @  30.3.2008,  15:20 Найти цитируемый пост)
Как она будет влиять на переменную в другом файле, если в другом файле не объявить наличие внешней переменной где-то, но использовать одноимённую ей там ?

можно использовать одноименную локальную переменную, тогда она скороет имя глабальной, и заменит ее.
Цитата(inside_pointer @  30.3.2008,  15:20 Найти цитируемый пост)
Будет выдана ошибка о недоступности глобальной переменной ?

да, если переменная не определена, но декларирована extern'ом



--------------------
Мой блог
PM MAIL WWW   Вверх
inside_pointer
Дата 31.3.2008, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Цитата(vinter)

можно использовать одноименную локальную переменную

нет, я имел ввиду не это, я имел в виду, что переменную используем как глобальную(то есть просто к ней обращаемся)

Цитата(vinter)

да, если переменная не определена, но декларирована extern'ом


Но видимо обращение к глобальной переменной без объявления внешней переменной - это то же самое что обращение к глобальной переменной с объявлением её как внешней переменной.
По крайней мере в книжке у меня сложилось такое впечатление, потому что они говорят что объявления extern можно опускать если определения находятся выше обращений и это обычная практика - обращаться к глобальной переменной, не объявляя её как требует стандарт.

PM MAIL   Вверх
Alek86
Дата 31.3.2008, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



inside_pointer, проведи пару экспериментов

похоже ты совсем неверно понял, что такое глобальные переменные в разных модулях и слово extern


--------------------
user posted image    user posted image
PM MAIL   Вверх
vinter
Дата 31.3.2008, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(inside_pointer @  31.3.2008,  13:33 Найти цитируемый пост)
По крайней мере в книжке у меня сложилось такое впечатление, потому что они говорят что объявления extern можно опускать если определения находятся выше обращений и это обычная практика - обращаться к глобальной переменной, не объявляя её как требует стандарт.

да, если определение находится в том же модуле. а если у тебя переменная определена в другом модуле, а ты хочешь юзать ее в этом? вот за этим и нужен extern. А вообще глобальные переменные это зло, старайся их избегать. 


--------------------
Мой блог
PM MAIL WWW   Вверх
MAKCim
Дата 31.3.2008, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(vinter @  31.3.2008,  12:50 Найти цитируемый пост)
А вообще глобальные переменные это зло, старайся их избегать.  

были уже топики на эту тему...
тупо следовать стереотипам - вот это зло



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
vinter
Дата 31.3.2008, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



MAKCim, я не говорю не юзай ГП никогда, я написал 
Цитата(vinter @  31.3.2008,  13:50 Найти цитируемый пост)
 старайся их избегать




--------------------
Мой блог
PM MAIL WWW   Вверх
MAKCim
Дата 31.3.2008, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(vinter @  31.3.2008,  15:04 Найти цитируемый пост)
я не говорю не юзай ГП никогда, я написал 

ты сказал, что глобальные переменные - это зло
к этому я и предрался


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
inside_pointer
Дата 1.4.2008, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Цитата(vinter)

а ты хочешь юзать ее в этом? вот за этим и нужен extern.

Если я не объявлю её, она выдаст ошибку ?

Цитата(Alek86)

похоже ты совсем неверно понял, что такое глобальные переменные в разных модулях и слово extern 

С чего ты взял что я неправильно понял ?
PM MAIL   Вверх
Alek86
Дата 1.4.2008, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(inside_pointer @  1.4.2008,  10:53 Найти цитируемый пост)
С чего ты взял что я неправильно понял ?

из-за
Цитата(inside_pointer @  30.3.2008,  01:57 Найти цитируемый пост)
Например есть файл, его считаем модулем, в нём определяем глобальную переменную, потом в этом файле(модуле) ссылаемся на неё через extern.

и т.д.

extern нужен только для того, чтобы 2 модуля использовали 1 переменную
Вся проблема в том, что компилер компилирует каждый cpp отдельно. Потому и придумали такой маневр с extern
Если бы он компилил сразу всю прогу (весь проект), то и ключевого слова extern не было бы


--------------------
user posted image    user posted image
PM MAIL   Вверх
vinter
Дата 1.4.2008, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(inside_pointer @  1.4.2008,  11:53 Найти цитируемый пост)
Если я не объявлю её, она выдаст ошибку ?

да


--------------------
Мой блог
PM MAIL WWW   Вверх
inside_pointer
Дата 1.4.2008, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Цитата(Alek86)

extern нужен только для того, чтобы 2 модуля использовали 1 переменную

Не, не только, ещё если определение глобальной переменной стоит ниже обращения к ней в одном модуле.

Ладно, vinter, спасибо, просвятил меня конкретно  smile 
PM MAIL   Вверх
UnrealMan
Дата 1.4.2008, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



inside_pointer, настоятельно рекомендую тебе почитать пункт стандарта 3.5 Program and linkage. А форумчанам ты особо не доверяй - в вопросах касательно linkage они разбираются не намного лучше тебя.

PM MAIL   Вверх
MAKCim
Дата 1.4.2008, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(inside_pointer @  1.4.2008,  14:27 Найти цитируемый пост)
Не, не только, ещё если определение глобальной переменной стоит ниже обращения к ней в одном модуле.

для этого используются прототипы


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
inside_pointer
Дата 2.4.2008, 04:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Я писал вот такую

Код


#include <stdio.h>

main()

{

extern int p;

p = 0;


}

int p;

//



Ошибок не выдал
PM MAIL   Вверх
Alek86
Дата 2.4.2008, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(inside_pointer @  1.4.2008,  14:27 Найти цитируемый пост)
Не, не только, ещё если определение глобальной переменной стоит ниже обращения к ней в одном модуле.

да ты прав, забыл

правда вероятность, что тебе придется эту возможность использовать практически равна 0, если прогу писать буш нормально (то есть все инклуды вверху cpp-шки и так далее)


--------------------
user posted image    user posted image
PM MAIL   Вверх
baldina
Дата 2.4.2008, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(MAKCim @ 1.4.2008,  22:07)
Цитата(inside_pointer @  1.4.2008,  14:27 Найти цитируемый пост)
Не, не только, ещё если определение глобальной переменной стоит ниже обращения к ней в одном модуле.

для этого используются прототипы

Что такое прототип переменной?
PM MAIL   Вверх
Alek86
Дата 2.4.2008, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



поскольку "прототип" - это объявление, а объявление переменной - это с ключевым словом extern, то extern int i; - это прототип переменной smile


--------------------
user posted image    user posted image
PM MAIL   Вверх
baldina
Дата 2.4.2008, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Не надо фантазий. Есть лишь понятие "function prototype". Которое есть форма вызова функции. Которая может являться частью объявления функции.
extern int i; - это объявление переменной
Если я неправ, покажите где про это в стандарте.
PM MAIL   Вверх
marcusmae
Дата 2.4.2008, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Ребят, если можно, у меня вопрос по теме :

Компилятор - MVC++ 9.0 (2008)

Я собрал несколько библиотек и прилинковал их к одному exe-шнику. Как импортировать/экспортировать функции и классы - сам знаю и другим объяснял уж никак не меньше 100 раз smile Да и в случае статических библиотек экспортировать ничего и не нужно. Так вот, как оказалось, с переменными понимания куда-меньше.

Правильно ли, что в библиотеке, которая должна содержать сами символы, я даю определения, например :

Код

const int MAXIOSTRINGLENGTH = 1024;

char iostring[MAXIOSTRINGLENGTH];


- iostring - это такая глобальная книга жалоб и предложений, в которую каждый класс в любой из библиотек должен иметь возможность излить свою проблему.

Следовательно, во всех других библиотеках я должен дать описания, как extern.

Код

extern const int MAXIOSTRINGLENGTH;

extern char iostring[MAXIOSTRINGLENGTH];


Правильно?






--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
bsa
Дата 2.4.2008, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Нет, неправильно. Нельзя задавать размер статического массива переменной.
Попробуй extern iostring[] или сделай MAXIOSTRINGLENGTH макросом (#define MAXIOSTRINGLENGTH 1024), что более соответствует способу именования (заглавными буквами принято называть макросы).
PM   Вверх
marcusmae
Дата 2.4.2008, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Цитата(bsa @  2.4.2008,  20:26 Найти цитируемый пост)
сделай MAXIOSTRINGLENGTH макросом


Сделал. Теперь работает, спасибо!


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
UnrealMan
Дата 2.4.2008, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Можно поместить

Код

const int MAXIOSTRINGLENGTH = 1024;

в заголовочный файл, поставляемый к библиотеке.
PM MAIL   Вверх
inside_pointer
Дата 3.4.2008, 03:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Цитата(Alek86)

правда вероятность, что тебе придется эту возможность использовать практически равна 0, если прогу писать буш нормально (то есть все инклуды вверху cpp-шки и так далее)


Не, вот допустим функции находятся не в конце а в начале, или откуда там она может вызываться в том же файле, тут она объявлена в функции main а может быть объявлена в других функциях, которые могут идти до main. Таким образом она будет стоять после них, быть в том же файле и, несмотря на то, что она определена ниже своего объявления в каждой из функций, исправно работать при этом, я уже всё выяснил сколько можно мусолить  smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1232 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.