Результаты оптимизации GCC приводят к появлению «неопределенного символа» во время выполнения - PullRequest
6 голосов
/ 30 марта 2011

У меня сейчас есть проблема, которая меня несколько смущает: у меня есть часть программного обеспечения, написанная на C ++ и связанная с библиотекой на C. Я включаю классы заголовков, используя обычный

extern "C" {
    #include <libheader.h>
}

Все работает нормально, пока я не использую оптимизацию gcc.Как только я включаю четный -O1, то есть первый уровень оптимизации, во время выполнения я получаю ошибку «неопределенный символ» для символа из этой библиотеки.Однако имя прошло через искажение имени, которое должно быть отключено из-за extern "C".

Функция, вызывающая соответствующий символ, является встроенной, если это имеет значение.Используется компилятор gcc 4.4.3.

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

Спасибо за вашу поддержку.

Ответы [ 4 ]

4 голосов
/ 30 марта 2011

Вы говорите, что включаете файл libheader.h в блок extern "C", но символ, который ищет компоновщик, был искажен.

Это признак того, что libheader.h также включается вне блока extern "C" (включение в блоке extern "C", вероятно, недопустимо из-за включения защиты в libheader.h).

Найдите другие способы, которыми libheader.h может быть включен. -E GCC и / или различные опции -M могут помочь, а могут и не помочь. Или (если только для теста) переместите блок extern "C" внутрь libheader.h:

// at start of libheader.h:
#ifdef __cplusplus
extern "C" {
#endif

/* existing contents of libheader.h */
// ...

// at end of libheader.h:
#ifdef __cplusplus
}
#endif

Обратите внимание, что спецификации связей могут быть вложенными, поэтому вам не нужно удалять существующие блоки extern "C" на сайтах #include.

Я не знаю, почему проблема возникла бы только для оптимизированных сборок, за исключением того, что, возможно, файл .c или .cpp, который содержит не встроенную версию вызывающей функции, правильно определяет заголовки, и нужно только один модуль перевода, который неправильно определяет заголовки и указывает на вызывающую функцию, чтобы увидеть проблему.

3 голосов
/ 30 марта 2011

Если у вас есть функция, которая определена, когда она не встроена, но не определена, когда она встроена, тогда проблема должна быть довольно простой для определения.

Вы где-то использовали функцию, не включая ее заголовочный файл.

Просмотрите все файлы, которые вызывают эту функцию, и убедитесь, что заголовок включен.

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

Возможно ли, что заголовок, который определяет вызывающую встроенную функцию, включает в себя заголовок библиотеки без оболочки extern "C" и везде, где используются строки оболочки?

Вы пробовалидругие уровни, такие как -O2?

Вы пытались удалить свою функцию?

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

Завершение заголовка C с extern "C" {...} не всегда работает; как правило, заголовки должны быть разработаны для работы с обоими языками для их для работы с обоими языками.

В этом случае без подробностей трудно сказать, что именно происходит, но ключевое слово inline означает разные вещи в C и в C ++; Я не ожидал бы, что заголовок с inline функциями будет работать в этом путь. (От руки, я бы не ожидал, что симптомы, которые вы получаете, но они меня тоже особо не удивляет.)

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

В противном случае, правильный способ справиться с этим - написать свой собственный C-код, который включает в себя заголовок и оборачивает все функции, которые вы нужно, и написать свой собственный заголовок для этого кода C, который предназначен для быть включены с обоих языков. Который, я признаю, много работы; заставить поставщика делать свою работу, вместо того, чтобы делать половину его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...