|
Использование extern в нескольких файлах |
|
|
|
 |
Ответов
|
Jan 24 2012, 07:33
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (XVR @ Jan 24 2012, 09:25)  Если программа на С (не С++ !) и переменная в обоих файлах не инициализированна, то она может быть объявленна хоть в 10 файлах. Фича такая в С. Линкер сделает одну переменную на все файлы Объявлена (с extern) она может быть сколько угодно раз, а определена (без extern и без static) может быть только в одном, что в С, что в С++.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 24 2012, 08:01
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(Сергей Борщ @ Jan 24 2012, 11:33)  Объявлена (с extern) она может быть сколько угодно раз, а определена (без extern и без static) может быть только в одном, что в С, что в С++. Нет, в С может много раз (хотя лучше так не делать) - test1.c Код int c;
int ret_c1(void) { return c; } test2.c Код int c;
int ret_c2(void) { return c; } test3.c Код #include <stdio.h>
extern int c;
int ret_c1(void); int ret_c2(void);
int main() { c=10; printf("c1=%d\n",ret_c1()); printf("c2=%d\n",ret_c2()); return 0; } Цитата > gcc test1.c test2.c test3.c -o testx > ./testx c1=10 c2=10 А вот если переменные будут инициализированны, тогда ой! Код int c=1; // В test1.c и test2.c Цитата > gcc test1.c test2.c test3.c -o testx /tmp/ccIqdWVQ.o:(.data+0x0): multiple definition of `c' /tmp/ccO4jRpV.o:(.data+0x0): first defined here collect2: ld returned 1 exit status Цитата Объявлена глобально переменная в разных модулях с одним и тем же именем. Понятно, что это 2 разные глобальные переменные в разных модулях. Нет, линкер сольет их в одну Цитата > gcc test1.c -c > objdump -t test1.o test1.o: file format elf64-x86-64 SYMBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 test111.c 0000000000000000 l d .text 0000000000000000 .text 0000000000000000 l d .data 0000000000000000 .data 0000000000000000 l d .bss 0000000000000000 .bss 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000000 g F .text 000000000000000c ret_c1 0000000000000004 O *COM* 0000000000000004 c Обратите внимание на '*COM*' (и тип O) у переменной 'c' - это COMMON секция. Линкер выберет одну (произвольно) такую секцию из всех входных файлов и замкнет все ссылки на нее
|
|
|
|
|
Jan 24 2012, 10:52
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(ViKo @ Jan 24 2012, 12:43)  Нет, это "чудесное" свойство компилятора, который вы используете, но никак не языка C. Я использовал gcc (один из самых распростаненных компиляторов). Но вынужден вас разочаровать - это свойство именно языка С. Стандарт С (99), глава 6.6.6: Linkages of identifiers Цитата 2 In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.
5 If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external. Так что для С слово extern и его отсуствие - одно и тоже
|
|
|
|
|
Jan 24 2012, 11:50
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(XVR @ Jan 24 2012, 13:52)  Стандарт С (99), глава 6.6.6: Linkages of identifiers Попытался перевести и понять, что там написано. П. 5 описывает функции, там другие правила. Единственное, что подходит - Each declaration of an identifier with no linkage denotes a unique entity. Но разве из этого следует, что эти уникальные объекты останутся уникальными, если они определены в разных файлах одной программы? Вот добавляем мы квалификатор static к определению переменной, чтобы ограничить ее видимость в пределах файла. Значит, без static она видна везде? Как же разруливать 2 одинаковых переменных?
|
|
|
|
|
Jan 24 2012, 14:18
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(ViKo @ Jan 24 2012, 15:50)  Единственное, что подходит - Each declaration of an identifier with no linkage denotes a unique entity. Но разве из этого следует, что эти уникальные объекты останутся уникальными, если они определены в разных файлах одной программы? Они будут уникальными по именам для всей программы, в скольких бы модулях их не описали. Вот - Цитата In the set of translation units and libraries that constitutes an entire program, Что можно перевести как 'в наборе единиц компиляции и библиотек, который является всей программой' Цитата П. 5 описывает функции, там другие правила. Во 2м предложении оттуда речь идет уже о переменных (я немного не то предложение выделил) Цитата Вот добавляем мы квалификатор static к определению переменной, чтобы ограничить ее видимость в пределах файла. Значит, без static она видна везде? Да Цитата Как же разруливать 2 одинаковых переменных? Их объединит линкер (если они обе не инициализированные), или получите слом на линковке
|
|
|
|
Сообщений в этой теме
kolobochishe Использование extern в нескольких файлах Jan 24 2012, 06:18 Палыч Цитата(kolobochishe @ Jan 24 2012, 10:18)... Jan 24 2012, 06:34     ReAl Цитата(XVR @ Jan 24 2012, 10:41) Как види... Jan 24 2012, 11:41      Палыч Цитата(ViKo @ Jan 24 2012, 15:50) Но разв... Jan 24 2012, 12:00 kolobochishe да. На простом Си. Не инициализирована.
Забавно. ... Jan 24 2012, 07:57 kolobochishe хм... а ИАР мне так не разрешает. Объявления без и... Jan 24 2012, 08:11 demitar хм, заинтриговали, у меня IAR'овский линкер на... Jan 24 2012, 08:12 kolobochishe а так у меня
Error[Li006]: duplicate definitions... Jan 24 2012, 08:20 demitar у меня старый иар, поэтому сообщения отличаются, н... Jan 24 2012, 08:25 kolobochishe Понятно Спасибо за разъяснения. Почему то всегда ... Jan 24 2012, 08:30 XVR Цитата(kolobochishe @ Jan 24 2012, 12:30)... Jan 24 2012, 08:41 andrew_b По умолчанию в Си переменные имеют внешнее связыва... Jan 24 2012, 12:02 dxp QUOTE (andrew_b @ Jan 24 2012, 19:02) По ... Jan 24 2012, 15:49  andrew_b Нет, переменные. И функции тоже. Про константы утв... Jan 25 2012, 04:36   am1808 Цитата(andrew_b @ Jan 25 2012, 08:36) Нет... Feb 3 2012, 10:11 Marto XVR,
а мне помнится, что во исходном файле глобаль... Feb 14 2012, 05:42 XVR Цитата(Marto @ Feb 14 2012, 09:42) а мне ... Feb 14 2012, 08:18
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|