Вопрос по gcc, ld, linker, c++, undefined-reference – Есть ли способ игнорировать неиспользованные неопределенные ссылки?

6

Предположим, у меня есть два исходных файла -UndefErr.cpp:

#include <cstdio>

void UndefFunc();
void Func2(){UndefFunc();}

void Func1(){printf("Hi\n");}

Иmain.cpp:

void Func1();

int main(){
    Func1();
    return 0;
}

Как вы видите вUndefErr.cpp Func2() собирается вызвать ошибку, для него используется неопределенныйUndefFunc(), Однако основная функция не заботится оFunc2()! В соответствии ссоответствующий вопрос Я мог бы передать вариант--unresolved-символы = игнорирующие в объектно-файлы компоновщику, но я хочу что-то другое. Мне нужен компоновщик, чтобы знать, использовались ли где-то неопределенные функции, и только тогда произойдет сбой.

Причина задать такой странный вопрос в том, что я пытаюсь использоватьLwIPи трудно понять все его зависимости(Мне нужен только TCP / IP)и я не могу найти учебники в интернете. Так что я думал, что смогу собрать больше всего(или все) отдельно .c файлы и напишите несколько простых тестов, чтобы увидеть, что они делают. Но этот подход натыкается на «неопределенные ссылки», большинство из которых, вероятно, не имеют отношения к сценарию использования.

Я не понимаю вопроса. Компоновщик будет жаловаться, если встретит неопределенную функцию. BЈовић
кажется, что компоновщик может просто «выяснить», нужно ли даже разрешать ссылки ... одно решение, хотя, если не так много функций, делающих его громоздким, вы можете просто заглушить их в main.cpp .. напримерvoid UndefFunc() {} mark
@ mark no, в проекте очень много функций. И главная проблема, которую я не знаю, какие функции не используются, поэтому я хочу как-то автоматизировать это .. Hi-Angel
@ BЈовић, да, но если неопределенная функция не используется, возможно, имеет смысл просто игнорировать ее. Как игнорировать такие ссылки - это просто вопрос. Hi-Angel

Ваш Ответ

2   ответа
3

Проблема в том, что ваша неопределенная функцияявляется используемый. Код объекта дляFunc2 был создан, есть ссылка на несуществующийUndefFuncи это идет к компоновщику. Компилятор не может понять, что эта функция всегда будет неопределенной, поскольку существует несколько единиц перевода.

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

Я думаю, что стоит упомянуть, что в приведенном выше сценарии я должен отслеживать от_start функция, так как это первая функция, которая будет выполнена. Иначе я мог бы закончить с испорченным исполняемым файлом. Hi-Angel
Я искал вокруг, и я просто обнаружил, что, вероятно, мне нужно две вещи: использовать-fdata-sections -ffunction-sections в качестве флага, чтобы каждая функция находилась в своем собственном разделе (чтобы позволить компоновщику видеть ссылки между разделами), а затем компоновщик должен знать точную функцию (главный в моем случае), с которого нужно отслеживать ссылки. Я также только что обнаружил, чтоLD Это язык сценариев, так что, вероятно, я здесь - кажется, что нет стандартного способа делать то, что я хочу. Hi-Angel
4

С Gcc 4.8.2 мне удалось связать код без ошибок со следующим:

$ g++ -c main.cpp -O3 -flto
$ g++ -c UndefErr.cpp -O3 -flto
$ g++ main.o UndefErr.o -flto -O3 -o out

я знаю-flto заставит компоновщик вести себя так, как будто-fwhole-program был пройден, и все это была единая единица компиляции. А также-fwhole-program, согласно инструкции, соответствует правильному использованиюstatic на функции, что позволяет исключить неиспользуемую функцию из вывода (т.е. вы гарантируете компилятору, что все ваши функции не будут использоваться каким-либо другим кодом, возможно, динамически загружаемым, и единственная точка входа, которую вы гарантируете своим пользователям, - этоmain()).

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

Отлично, я никогда не знал об этом варианте! И да, без-O3 Чтобы быть переданным во время компиляции, компоновщик по какой-то причине отказывается прервать неиспользуемые функции. Hi-Angel
С помощью сборки MSYS2 MinGW GCC 5.3.0 я смог добиться устранения неиспользуемых функций и, следовательно, избежать ошибок «неопределенная ссылка» для символов, на которые ссылаются эти функции.-flto -Og параметры компилятора Richard Lang

Похожие вопросы