Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C++] Linker error door O1 optimalisatie

Pagina: 1
Acties:

  • liquid_ice
  • Registratie: Februari 2001
  • Laatst online: 19-11 07:22
In een al bestaand en wat groter project ben ik bezig om de O1 compiler optimalisatie van gcc aan te zetten.

Zonder deze O1 compiler optimalisatie bouwt, linkt en runt alles keurig netjes.
Als ik compileer met de O1 flag dan bouwt de main exacutable gewoon, maar krijg ik linker error's bij een van de unittesten.

tussen deze 2 compile slagen is geen code of makefiles aangepast, maar alleen de O1 optimalisatie aangezet.

de error die ik krijg is:
code:
1
2
Configuration.a(Builder.o): In function `Builder::Create() const':
Builder.cpp:123: undefined reference to `Factory::Instance()'


ergens bij het linken komt ie in de Builder.cpp op regel 123 deze call tegen:
cpp file
code:
1
pObject = Factory::Instance()->CreateObject();

(naast de linker error over de Instance, heb ik zo'n zelfde over de CreateObject functie)

Als ik dan kijk naar de Factory
header file
code:
1
2
3
4
5
class Factory
{
public:
    static Factory* Instance();
<< rest of the file >>


en in de cpp file
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}


Als eerste heb ik een gehele clean en rebuild gedaan, maar dat bood geen soelaas.
Ook heb ik met behulp van nm dumps gemaakt van de symbols van Factory.o (eentje met en eentje zonder optimalisatie) en deze vergeleken.

Ik zie dat er wat symbols verdwenen zijn, maar niet die van Factory::Instance(). wel zie ik dat er iets met de adressen is veranderd omtrend deze functie, maar dat lijkt me geen probleem.

Ook via google heb ik allerlei opties gevonden, maar niet wat mijn probleem lijkt te zijn.

Heeft iemand een idee in welke hoek dat ik het kan zoeken?

[ Voor 4% gewijzigd door liquid_ice op 20-03-2013 17:40 ]

Klus page: http://klusthuis.blogspot.com


  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 22:51

leuk_he

1. Controleer de kabel!

Compiler versie kan bij zo'n specifieke issue belangrijk zijn, als je gaat googlen.

Verder is O1 een verzameling.

Wellicht kun je specifieker terugvinden welke Optimalisatie het is.
fauto-inc-dec
-fcprop-registers
-fdce
-fdefer-pop
-fdelayed-branch
-fdse
-fguess-branch-probability
-fif-conversion2
-fif-conversion
-finline-small-functions
-fipa-pure-const
-fipa-reference
-fmerge-constants
-fsplit-wide-types
-ftree-builtin-call-dce
-ftree-ccp
-ftree-ch
-ftree-copyrename
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-fre
-ftree-sra
-ftree-ter
-funit-at-a-time
En het zou me ook niet verbazen als make clean niet goed werkt. ;)

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


  • liquid_ice
  • Registratie: Februari 2001
  • Laatst online: 19-11 07:22
We gebruiken gcc 4.3.3

De lijst die je post is inderdaad wel handig, alleen zie ik dat de 4.3.4 (en ik vermoed dus ook de 4.3.3) versie een O1 optimalisatie (de ftree-builtin-call-dce) niet ondersteunt die wel in jou lijst van 4.4 staat

zie: http://gcc.gnu.org/online...ons.html#Optimize-Options

Het wordt er niet echt duidelijker op...

Als ik een clean doe en dan de lijst met bovenstaande O1 onderdelen, dan krijg ik de compiler melding dat onze target geen delayed branches heeft.
Als ik de -fdelayed-branch eruit haal compileert en linkt ie helemaal goed.
Maar met O1 dus niet.

[ Voor 30% gewijzigd door liquid_ice op 21-03-2013 09:46 ]

Klus page: http://klusthuis.blogspot.com


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-11 03:08
Om te zien welke optimalisaties precies gebruikt worden, kun je ook dit commando gebruiken:
gcc -O1 -Q --help=optimizers

... en dan inderdaad dingen aan/uit proberen te zetten tot het stuk gaat. Rotwerk; en het kan goed zijn dat het niet één specifieke optie is waardoor het misgaat, maar een combinatie van opties.

Als je een compilerfout vermoedt, is het misschien handiger om de compiler te upgraden; de laatste release is 4.8.0 (en de oudste supported versie is 4.6.3, maar die is ook al twee jaar oud). Als dat je probleem oplost scheelt dat sowieso een hoop uitzoekwerk.

Verder nog wat ongevraagd programmeeradvies. Je kunt Factory::Instance() ook zo implementeren:
C++:
1
2
3
4
5
Factory* Factory::Instance()
{
    static Factory *sInstance = new  Factory();
    return sInstance;
}

... dan zorgt de compiler ervoor dat sInstance de eerste keer geïnitialiseerd wordt. In tegenstelling tot je huidige implementatie is dit wél threadsafe.

En het kan zelfs nog simpeler:
C++:
1
2
3
4
5
Factory* Factory::Instance()
{
    static Factory sInstance;
    return &sInstance;
}

... met het belangrijkste verschil dat de compiler nu zorgt dat de destructor aangeroepen wordt (wat ook betekent dat je de controle verliest over wanneer dat exact gebeurt).

  • liquid_ice
  • Registratie: Februari 2001
  • Laatst online: 19-11 07:22
Kijk, een stap in de richting.

als ik O1 aanzet dan worden deze opties aangezet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  -fcprop-registers           Perform a register copy-propagation optimization pass
  -fdefer-pop                 Defer popping functions args from stack until later
  -fguess-branch-probability  Enable guessing of branch probabilities
  -fif-conversion             Perform conversion of conditional jumps to branchless equivalents
  -fif-conversion2            Perform conversion of conditional jumps to conditional execution
  -fipa-pure-const            Discover pure and const functions
  -fipa-reference             Discover readonly and non addressable static variables
  -fmerge-constants           Attempt to merge identical constants across compilation units
  -fomit-frame-pointer        When possible do not generate stack frames
  -fsplit-wide-types          Split wide types into independent registers
  -ftree-ccp                  Enable SSA-CCP optimization on trees
  -ftree-ch                   Enable loop header copying on trees
  -ftree-copy-prop            Enable copy propagation on trees
  -ftree-copyrename           Replace SSA temporaries with better names in copies
  -ftree-dce                  Enable SSA dead code elimination optimization on trees
  -ftree-dominator-opts       Enable dominator optimizations
  -ftree-dse                  Enable dead store elimination
  -ftree-fre                  Enable Full Redundancy Elimination (FRE) on trees
  -ftree-salias               Perform structural alias analysis
  -ftree-sink                 Enable SSA code sinking on trees
  -ftree-sra                  Perform scalar replacement of aggregates
  -ftree-ter                  Replace temporary expressions in the SSA->normal pass
  -funit-at-a-time            Compile whole compilation unit at a time


Eerste eens een compile run met al deze opties om te kijken of ik dan dezelfde melding krijg als met de O1 ;)

Klus page: http://klusthuis.blogspot.com


  • liquid_ice
  • Registratie: Februari 2001
  • Laatst online: 19-11 07:22
Even om het topic af te sluiten...

Met de O1 optimalisatie aan bleef ik link error's houden, maar met bovenstaande lijst van opties aan had ik geen error's.

Met de bovenstaande opties EN ook nog de O1 had ik ook linker error's.

Uiteindelijk heb ik de lijst met linker libs verwijderd en ben deze opnieuw gaan opbouwen aan de hand van de linker error's die ik toen kreeg.
Ik weet dus nog steeds niet waardoor het probleem nu precies is veroorzaakt, maar het is wel opgelost...

Klus page: http://klusthuis.blogspot.com


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:38

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op donderdag 21 maart 2013 @ 15:05:
... dan zorgt de compiler ervoor dat sInstance de eerste keer geïnitialiseerd wordt. In tegenstelling tot je huidige implementatie is dit wél threadsafe.
Let wel dat dat pas vanaf C++11 geldt, en nog lang niet alle compilers dat gedrag implementeren.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-11 03:08
GCC (wat de TS gebruikt) deed dat al een tijdje, ook als je een veel oudere standaard target. Het klopt dat je die garantie toen inderdaad niet had op basis van de C++ spec zelf.
Pagina: 1