2014-07-01 17 views
8

Mam funkcjiJak wyłączyć automatyczną optymalizację "przejścia przez wskaźnik" w języku ++?

void X(Object o) 
{ 
.... 
} 

Kiedy skompilować go, widzę, że dzyń zmienia swój podpis

void X(Object* o) 

Jest to niewygodne, ponieważ używam tej funkcji z jakiegoś LLVM kodu IR bezpośrednio. Jak zabezpieczyć się przed zrobieniem tej optymalizacji?

Edit: Minimal przykład praca:

#include <stdio.h> 

class Object 
{ 
public: 
    Object(); 
    ~Object(); 
    int* pointer; 
}; 

void Function(Object o) 
{ 
    o.pointer = 0; 
} 

int main() 
{ 
    Object a; 
    Function(a); 
    return 0; 
} 

Przy następnym wierszu poleceń:

clang++ tst.cpp -emit-llvm -O0 tst.cpp -S -std=c++11 

Function przekłada się na:

define void @_Z8Function6Object(%class.Object* %o) nounwind uwtable { 
    %1 = getelementptr inbounds %class.Object* %o, i32 0, i32 0 
    store i32* null, i32** %1, align 8 
    ret void 
} 
+3

To część ABI. –

+0

Czy próbowałeś wyłączyć wszystkie optymalizacje za pomocą przełącznika -O0? –

+0

Tak, -O0 jest włączone – Necto

Odpowiedz

2

Trzeba dodać opcja -mdisable-fp-elim

Wyłącz optymalizację eliminacji wskaźnika ramki.

Tu gdzie mogę znaleźć tej opcji: clang option

I tu również wyjaśnienie, dlaczego dzyń to zrobić: understand option 'omit frame pointer'

* Edycja: *

Po pewnym inspekcji znalazłem to:

  • Twój obiekt jest prawidłowo przechodzić przez kopią po compilling:

przykład:

#include <stdio.h> 
#include <iostream> 

class Object 
{ 
public: 
    std::string test; 
    Object() { 
    this->test = "I'm an object"; 
    std::cout << "Object created" << std::endl; 
    } 
    Object(Object &o) { 
    this->test = "I'm a object copy"; 
    std::cout << "Object copy created" << std::endl;  
} 
    ~Object() { 
} 
    int* pointer; 
}; 

void Function(Object o) 
{ 
    o.pointer = 0; 
    std::cout << o.test << std::endl; 
} 

int main() 
{ 
    Object a; 
    Function(a); 
    std::cout << a.test << std::endl; 
    return 0; 
} 

wyjściowa:

obiekt utworzony

kopia obiektu utworzonego

jestem kopią obiektu

Jestem obiektowi

  • Drugi punkt:

można zobaczyć tuż po prototypie funkcji

; Function Attrs: uwtable 
define void @_Z8Function6Object(%class.Object* %o) #3 { 
    %1 = getelementptr inbounds %class.Object* %o, i32 0, i32 1 // Get 
    store i32* null, i32** %1, align 8 

że funkcja uzyskać kopię obiektu.Można zobaczyć w main kopii obiektu

Więc kod wydaje się działać dobrze w rzeczywistości;)

+0

Nie działa dla mnie. 'clang: warning: argument nieużywany podczas kompilacji: '-mdisable-fp-elim'' Zobacz Czy działający przykład, dodany powyżej – Necto

+0

nie jest clang ++ zgodny z gcc w jego konwencji wywoływania? '-fomit-frame-pointer'would będzie wersją gcc i' -fno-omit-frame-pointer', aby wyłączyć. – Alex

+0

@Alex, '-fno-omit-frame-pointer' nie działał dla mnie ani – Necto