c ошибка компилятора при компоновке - PullRequest
0 голосов
/ 14 февраля 2012

Вот ошибка, которую я получаю от вызова gcc:

gcc -o rr4 shells2.c graph1.c rng.c;

  Undefined symbols:  
   "_getdisc", referenced from:  
       _main in cckR7zjP.o  
  ld: symbol(s) not found

"cckR7zjP.o" постоянно меняется каждый раз, когда я вызываю компилятор.Код для метода находится в файле graph1.c;его заголовочный файл называется graph2.h, и я импортирую его в файл с основным методом, называемым shells2.c, используя:

#include "graph2.h"

Определение метода или функции:

int getdisc(int i){ return disc[i];}

, который пытается вернуть элемент i th диска массива, созданный

static int *disc;  

, который я уже инициализировал в другом методе!Я думаю, что проблемный вызов:

for (iter = 0; iter < n; iter++) {
    if (getdisc(iter) == cln)
        avgbtwn += get_betweenness(iter);
}

Это похоже на проблему компоновщика. Я проверил некоторые другие вопросы и думаю, что я правильно связываю свой метод (и использую тот же метод в другом месте кода).но я до сих пор не могу понять это.

Редактировать: поэтому я изменил порядок команды в Linux на

gcc -o rr4 graph1.c rng.c shells2.c   

в соответствии с предложением Сорена, и функция, скомпилированная как обычно, делаеткто-нибудь знает почему?Кроме того, кажется, что когда я вставляю разрыв строки в файле graph1.c, это облегчает проблему.

Ответы [ 2 ]

2 голосов
/ 14 февраля 2012

Раньше в старых компиляторах / компоновщиках GCC 2.x существовала проблема, из-за которой компоновщик не мог разрешить линковку, когда символы не были сгруппированы - подумайте, что компоновщик будет искать только те символы, которые все еще необходимо, и это будет отбрасывать символы, которые не использовались.

Для большинства людей эта проблема проявляется как проблема упорядочения библиотек (указывается с -l или как .a).

Я вижу из комментариев, что вы используете Mac, так что может быть просто тем, что версия компилятора / компоновщика для Mac все еще имеет эту проблему - в любом случае, так как переупорядочивание исходных файлов решило проблему, тогда у вас наверняка есть какой-то вариант этой ошибки.

Итак, возможные решения;

  1. Сгруппировать все ваши исходные файлы в большие файлы - плохое решение - но компоновщик с меньшей вероятностью потерпит неудачу с этим симптомом - или
  2. Попробуйте сначала скомпилировать все файлы в .o, а затем связать файлы .o (обычно это можно сделать с помощью make-файла, но это может решить проблему, а может и не решить) и, возможно, объединить .o в один файл .a ( man ar) или
  3. Измените порядок исходных файлов, чтобы иметь последний shells2.c (который работал для вас), или
  4. Посмотрите, поможет ли обновление вашего компилятора

Извините за длинный список белья, но это явно ошибка компилятора, которую нужно просто обойти.

2 голосов
/ 14 февраля 2012

Это определенно ошибка, так как getdisc не виден компоновщику, но, если то, что вы говорите правильно, этого не произойдет.

Ваша командная строка gcc включает в себя graph1.c, которую, как вы уверены, используете, содержит функцию.

Не беспокойтесь об имени объектного файла, это просто временное имя, созданное компилятором для передачи компоновщику.

Можете ли вы подтвердить (точно вырезать и вставить) используемую командную строку gcc и показать нам определение функции с некоторым контекстом вокруг нее?

Кроме того, убедитесь, что graph1.c компилируется, как ожидается, вставив непосредственно перед функцией getdisc следующую строку:

xyzzy plugh twisty;

Если ваша функция просматривается компилятором, это должно сначала вызвать ошибку . Это может быть что-то вроде ifdef операторов, приводящих к тому, что ваш код не будет скомпилирован.

В порядке тестирования следующая транскрипция показывает, что то, что вы пытаетесь сделать , прекрасно работает:

pax> cat shells2.c
    #include "graph2.h"
    int main (void) {
        int x = getdisc ();
        return x;
    }


pax> cat graph2.h
int getdisc (void);

pax> cat graph1.c
    int getdisc (void) {
        return 42;
    }


pax> gcc -o rr4 shells2.c graph1.c 

pax> ./rr4

pax> echo $?
42

Поэтому мы должны предположить, что то, что вы на самом деле делаете, является чем-то другим, и это необычно тактично для меня: -)

То, что вы испытываете, это то, что происходит с чем-то вроде:

pax> gcc -o rr4 shells2.c
/tmp/ccb4ZOpG.o: In function `main':
shells2.c:(.text+0xa): undefined reference to `getdisc'
collect2: ld returned 1 exit status

или если getdisc было , а не , объявлено правильно в graph1.c.

Этот последний случай может быть по многим причинам, включая, но не ограничиваясь:

  • неправильное написание getdisc.
  • #ifdef операторы типа, означающие, что определение никогда не видели (хотя вы, кажется, обесценили это в комментарии).
  • некоторые шутки, использующие #define для изменения getdisc на что-то другое (маловероятно, но возможно).
...