#c #c #gcc #linker-errors #cl
#c #c #gcc #ошибки компоновщика #cl
Вопрос:
Я написал следующую тестовую программу
int proc1();
extern int globalvar;
int func1 ()
{
return globalvar 1;
}
int func2()
{
return proc1() 3;
}
int main()
{
return 0;
}
Как вы можете видеть, эта программа ничего не делает. Однако при компиляции я столкнулся с ошибкой компоновщика globalvar
и int proc1()
, несмотря на то, что на них не будут ссылаться из функции точки входа main
.
Я столкнулся с проблемой как в Windows (используя cl
), так и в Linux (используя gcc
).
Есть ли какой-либо способ дать указание компилятору / компоновщику не связывать эту глобальную переменную и функцию без ссылок с точки входа (на cl, gcc и clang)?
Точное сообщение об ошибке в Windows:
test.obj : error LNK2019: unresolved external symbol "int globalvar" (?globalvar@@3HA) referenced in function "int __cdecl func1(void)" (?func1@@YAHXZ)
test.obj : error LNK2019: unresolved external symbol "int __cdecl proc1(void)" (?proc1@@YAHXZ) referenced in function "int __cdecl func2(void)" (?func2@@YAHXZ)
test.exe : fatal error LNK1120: 2 unresolved externals
Комментарии:
1.
these are not going to be used in the program
— тогда что вы думаетеreturn globalvar 1;
иreturn proc1() 3;
делаете?2. @user3477950: Смотрите правку. На них нельзя ссылаться из функции точки входа main.
3. и что потом? их вызывающие устройства не являются таковыми
static
, поэтому, даже если компоновщик выполняет LTO, он не может их устранить…4. @user3477950: Это потому, что эти функции могут использоваться в другой единице перевода? Но у меня есть только одна единица перевода.
5. @dbasic я думаю, у вас возникла ошибка неопределенного указания. где вы определили
proc1()
функцию. иglobalvar
переменной.
Ответ №1:
Вы можете исправить это gcc
следующим образом:
gcc -ffunction-sections -Wl,--gc-sections test.c
Это делает две вещи:
-
Он инструктирует компилятор выдавать каждую функцию в ее собственном «разделе» в двоичном файле.
-
Он предписывает компоновщику удалить (собрать мусор) разделы, на которые нет ссылок.
Это означает, что func1
и func2
будут отброшены, и, следовательно, больше не будет ссылок на globalvar
or proc1
.
Комментарии:
1. Понятия не имею, вы тот, кто на самом деле использовал эти инструменты. 😉