Цитата(Сергей Борщ @ 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 секция. Линкер выберет одну (произвольно) такую секцию из всех входных файлов и замкнет все ссылки на нее