2014-06-11 13 views
6

Załóżmy, że mam dwa pliki źródłowe - UndefErr.cpp:Czy istnieje sposób na zignorowanie nieużywanych niezdefiniowanych odniesień?

#include <cstdio> 

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

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

a main.cpp:

void Func1(); 

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

Jak widać w UndefErr.cppFunc2() dzieje aby wywołać błąd, ponieważ używa niezdefiniowanego UndefFunc(). Jednak główna funkcja nie dba o Func2()! Według a relevant question mogę przekazać opcję --unresolved symboli = ignore-in-obiektowe plików z łącznikiem, ale chcę trochę inna sprawa. Potrzebuję linkera, żeby sprawdzić, czy niezdefiniowane funkcje są gdzieś używane, a dopiero potem zawodzą.

Powodem prosząc takie dziwne pytanie jest to, że staram się używać lwIP i trudno jest zrozumieć wszystkie jego zależności (I wystarczy TCP/IP), i nie mogę znaleźć samouczki w Internecie. Więc pomyślałem mogłem skompilować najbardziej (lub wszystkie) się .c pliki osobno i napisać kilka prostych testów, aby zobaczyć, co robi. Ale takie podejście natrafia na "nieokreślone odniesienia", większość z nich prawdopodobnie nie ma związku z przypadkiem.

+0

wydaje się, jakby łącznikiem może po prostu „dowiedzieć się” w razie potrzeby nawet do rozwiązania referencje ... jedno rozwiązanie jest jednak, jeśli nie ma wiele funkcji, które sprawiają, że można po prostu uciążliwe skrótową je w głównym. cpp ... eg 'void UndefFunc() {}' – mark

+0

@mark no, w projekcie bardzo wiele funkcji. I główny problem, którego nie znam, którego funkcje nie są używane, dlatego chcę jakoś zautomatyzować to ... –

+0

Nie rozumiem pytania. Łącznik będzie narzekał, jeśli napotka nieokreśloną funkcję. –

Odpowiedz

4

z gcc 4.8.2 udało mi się połączyć kodu bez błędów z następujących czynności:

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

wiem -flto sprawi, że zachowuje się tak, jakby -fwhole-program łącznik została uchwalona i cała sprawa była pojedyncza jednostka kompilacja . I -fwhole-program, według instrukcji, odpowiada prawidłowego wykorzystania static na funkcje, więc pozwalając nieużywany funkcja zostać wyeliminowane z wyjścia (to znaczy zapewnić kompilator wszystkie funkcje nie będą wykorzystywane przez inny kod, ewentualnie załadowane dynamicznie , a jedynym punktem, który gwarantujesz swoim użytkownikom, jest main()).

Musiałem dodać , nie jestem pewien, dlaczego dokładnie, ale kompilator nie był bardzo zainteresowany w sprawdzaniu funkcji i eliminacji martwego kodu bez niego.

+0

Doskonale, nigdy nie znałem tej opcji! I tak, bez "-O3", które należy przekazać w czasie kompilacji, linker z jakiegoś powodu odmawia przerwania nieużywanych funkcji. –

+1

Dzięki kompilacji MSYS2 z GG 5.3.0 MinGW udało mi się wyeliminować nieużywane funkcje i uniknąć błędów "nieokreślonego odniesienia" dla symboli funkcji wymienionych w opcjach kompilatora '-flto -Og' –

3

Problemem jest to, że jest niezdefiniowana funkcja używany. Kod wynikowy dla Func2 został wygenerowany, istnieje odniesienie do nieistniejącego UndefFunc, i idzie do łącznika. Kompilator nie ma możliwości zrozumienia, że ​​ta funkcja będzie zawsze niezdefiniowana, ponieważ istnieje wiele jednostek tłumaczeniowych.

Jedynym sposobem na uniknięcie błędu kompilacji jest powiedzenie linker, że nie potrzebujesz kodu obiektowego dla nieużywanych funkcji, aby nie próbował generować zespołu dla tego przypadku.

+1

Szukałem w pobliżu i właśnie odkryłem, że prawdopodobnie potrzebuję dwóch rzeczy: użyć '-fdata-sections -ffunction-sections' jako flagi, aby każda funkcja znajdowała się w jej własnej sekcji (aby umożliwić linker do zobacz referencje między sekcjami), a następnie linker musi znać dokładną funkcję (* główny * w moim przypadku), z którego należy śledzić referencje. Zauważyłem też, że * LD * ma język skryptowy, więc prawdopodobnie tutaj idę - wydaje się, że nie ma standardowego sposobu robienia tego, co chcę. –

+0

Myślę, że warto wspomnieć, że w powyższym scenariuszu powinienem śledzić funkcję '_start', ponieważ jest to pierwsza funkcja do wykonania. Inaczej mógłbym skończyć z uszkodzonym plikiem wykonywalnym. –

Powiązane problemy