класс extern: неопределенная ссылка при портировании с gcc 3.x на 4.x - PullRequest
1 голос
/ 04 марта 2011

Я портирую какой-то ужасный унаследованный код C ++ с gcc 3.x на 4.x В заголовочном файле есть конструкция, которая выглядит следующим образом:

extern class ErrorLog
{
   . . .
} error_log, debug_log;

В 3.x он компилируется и работает нормально, но в 4.x я получаю много ошибок вида

undefined reference to `error_log'

undefined reference to `ErrorLog::log(ErrorLog::LogAttr const&, char const*, ...)'

Ответы [ 3 ]

1 голос
/ 04 марта 2011

Я думаю, что это связано с сообщением об ошибке Я недавно отправил GCC.Вопрос в том, определяет ли это тип class ErrorLog или нет?Я предлагаю вам разделить определение и объявления следующим образом:

class ErrorLog{...};
extern ErrorLog error_log, debug_log;

Предположительно class ErrorLog определено и где-то еще - в идеале вы должны изменить это так, чтобы оно определялось только один раз.

0 голосов
/ 06 марта 2011

Решение оказалось простой задачей компоновки линкера.Определение error_log находилось в библиотеке, указанной в начале командной строки, но не использовалось до позднего времени.Линкер 4.x не должен отслеживать определенные символы так, как линкер 3.x.Добавление -Xlinker --whole-archive в начале решило проблему, хотя, естественно, это раздуло объект.

Изменение порядка также сработало бы, но набор архивов генерируется автоматически, так что это сложнее без радикальной перезаписи Make-файла.

0 голосов
/ 04 марта 2011

Extern - это декларация, а не определение.Поэтому вы только объявляете name error_log и debug_log, но не выделяете для них место в памяти.У вас должно быть определение этих переменных где-то еще (возможно, в файле .cpp).

Этого может быть достаточно в исходном файле, который включает указанный вами заголовочный файл: ErrorLog error_log, debug_log;

Иметь полное определение класса в объявлении extern странно.

...