W już istniejącym i dość dużym projekcie, włączam optymalizację kompilatora gcc O1
.Błąd Linker C++ podczas korzystania z optymalizacji O1
Bez tej opcji wszystko buduje, łączy i działa poprawnie. z włączoną opcją, główny plik wykonywalny kompiluje i łączy, ale otrzymuję błędy linkera podczas łączenia jednego z testów jednostkowych.
Pomiędzy tymi 2 uruchomieniami kompilacji nie zmieniłem żadnego kodu ani nie utworzyłem plików, tylko flaga optymalizacji O1
.
Błąd, który pojawia się:
Configuration.a(Builder.o): In function `Builder::Create() const':
Builder.cpp:123: undefined reference to `Factory::Instance()'
Gdzieś w trakcie procesu łączenia, napotka tę linię (linia 123) z Builder.cpp
: plik cpp
pObject = Factory::Instance()->CreateObject();
(oprócz błędu łącznikowej funkcji Instance
, otrzymuję także jedną z funkcji CreateObject
)
Kiedy patrzę na e Factory
widzę: Plik nagłówek
class Factory { public:
static Factory* Instance(); << rest of the file >>
A w pliku cpp
Factory* Factory::sInstance = 0;
Factory* Factory::Instance() {
// Check if this is the first call
if (sInstance == 0)
{
// Create only instance
sInstance = new Factory();
}
// Address of the instance
return sInstance; }
Najpierw próbowałem to czysty i odbudować, ale to nic nie robić. również użyłem nm, aby zrobić zrzuty używanych symboli Factory.o
(jeden z i bez optymalizacji) i porównać je.
Widzę, że niektóre symbole są usuwane, ale nie jeden Factory::Instance()
. Widzę coś z adresem zmienionym w odniesieniu do tej funkcji, ale nie spodziewam się, że to będzie problem.
Również przez Google Znalazłem kilka możliwości, ale nie mogłem znaleźć czegoś, co pasowałoby do mojego problemu.
Czy ktoś ma pomysł, jak znaleźć ten problem?
Wersja kompilatora? Jak ją skompilować (czy plik Makefile jest na tyle krótki, aby móc go opublikować?)? Czy upewniłeś się, że to jedyna rzecz, którą zmieniłeś (np. Jeśli wyjmiesz '-O1', czy znowu się skompiluje)? – us2012
Oprócz braku bezpieczeństwa na wątku i mylącej nazwy ("Fabryka" jest raczej czymś w rodzaju singletona), nie widzę nic niepożądanego w kodzie, który pokazałeś.Jeśli '-O1' jest naprawdę jedyną zmianą, to powinno działać dobrze. O ile w makefile nie ma klauzuli warunkowej, która nie kompiluje 'factory.cpp' lub czegoś, gdy optymalizacje są włączone, ale to byłoby trochę śmieszne (może bardzo to wykluczyć!). – Damon