Две статические переменные с одинаковым именем (два разных файла) и extern одна из них в любом другом файле

Объявление переменной как статической в ​​одном файле и объявление extern в другом файле - я думал, что это приведет к ошибке при связывании, поскольку переменная extern не будет видна ни в одном объекте, поскольку та, которая была объявлена ​​в другом файле, была с квалификатором static . Но каким-то образом компоновщик (renesas) не показал никаких ошибок и создал исполняемый файл.

Если приведенный выше вариант использования был правильным, что произойдет, если две переменные будут объявлены как статические в двух разных файлах, а другая - в другом файле с объявлением extern? В этом случае 2 разных памяти будут созданы в 2 разных объектах, но какая из переменных будет связана с другой переменной, которая была объявлена ​​как extern в другом файле (поскольку имена переменных одинаковы) ??

file1.c

static int test_var;
fn1()
{
   test_var = 1;
}    

file2.c

static int test_var;
fn2()
{
   test_var = 2;
}

file3.c

extern int test_var;
fn3()
{
   int x;
   x = test_var;
}

person Opener    schedule 15.12.2013    source источник
comment
@ H2CO3, пример кода обновлен ...   -  person Opener    schedule 15.12.2013
comment
Нет определения для test_var объявленного extern и нет определения для main. Мой компоновщик отмечает обе ошибки. Покажите полный пример.   -  person CB Bailey    schedule 15.12.2013
comment
Это должно привести к ошибке компоновщика, и это происходит в моем случае (с использованием clang в OS X): Неопределенные символы для архитектуры x86_64: _test_var, на которые есть ссылка: _fn3 в file3.o   -  person Martin R    schedule 15.12.2013
comment
С этим кодом возникает ряд проблем. Я считаю 7 предупреждений плюс ошибки компоновщика (_test_var и _main) только с предупреждениями по умолчанию (clang / OSX)   -  person Kevin    schedule 15.12.2013


Ответы (3)


Ответ, вероятно, заключается в том, что вы настроили компоновщик. Если вы подключаете библиотеку, все будет в порядке, и модуль file3.o будет иметь test_var ссылку как UNDEFINED.

Если вы связываете приложение из этих трех модулей, вы потерпите неудачу только потому, что отсутствие main() определения подпрограммы и неразрешенный внешний вид будет считаться еще меньшим злом. :-)

Чтобы проверить это, просмотрите соответствующие *.o таблицы символов модулей в процессе сборки, а затем окончательный результат. При таком подходе вы обнаружите причину своего странного поведения сборки.

person Roman Nikitchenko    schedule 15.12.2013

В вашем примере file3.c не имеет абсолютно доступа к переменной test_var ни в file1.c, ни в file2.c. Вы должны получить ошибку связывания, если test_var не объявлен в рамках file3.c.

person Fiddling Bits    schedule 15.12.2013

В файлах file1.c и file2.c ключевое слово static означает, что переменная test_var является областью файла. Это означает, что эта переменная доступна только в том файле, в котором она объявлена.

В файле file3.c ключевое слово extern означает, что переменная объявлена ​​в другом файле.

Когда компилятор компилирует file3.c, он пометит, что переменная test_var находится в другом объектном файле, и не заботится о том, где она находится. Таким образом, этот файл можно скомпилировать, и никаких ошибок не возникло. Но когда компоновщик обработает эти объектные файлы, он обнаружит, что никакая переменная с именем test_var не может быть связана с файлом3, будет показана ошибка.

person MicroAleX    schedule 15.12.2013
comment
static означает статическую связь, а не область файла, а объявление extern в file3.c означает, что определение для этой переменной есть где-то еще, объявление уже там. - person effeffe; 15.12.2013
comment
@effeffe Прошу прощения за свою ошибку, я снова прочитал документ ISO, вы правы. - person MicroAleX; 15.12.2013