Ошибка компоновщика неиспользуемой переменной и функции

#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
  

Это делает две вещи:

  1. Он инструктирует компилятор выдавать каждую функцию в ее собственном «разделе» в двоичном файле.

  2. Он предписывает компоновщику удалить (собрать мусор) разделы, на которые нет ссылок.

Это означает, что func1 и func2 будут отброшены, и, следовательно, больше не будет ссылок на globalvar or proc1 .

Комментарии:

1. Понятия не имею, вы тот, кто на самом деле использовал эти инструменты. 😉