PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : inline Funktionen und Kopien


Gast
2007-11-19, 11:18:27
Hi,

wenn ich eine Funktion zum Konvertieren von einem Struct in einen anderen Typ habe in etwa dieser Form:

Foob convert( const Noob& e )
{
Foob retr;
// [...]
return retr;
};

Jetzt muß jedesmal das Struct vom Typ Foob kopiert werden. Ich will darin aber keinen Heap-Speicher anfordern, noch einen Pointer auf einen Speicherbereich mitgeben.

Kann man dennoch eine Kopieroperation sparen, und zwar wenn ich die Funktion inline definiere? inline Foob convert( const Noob& e );

danke

Gast
2007-11-19, 11:22:53
Ich lese gerade, daß der Compiler sich da auch anders verhalten kann. Er muß trotz inline nicht inlinenen und kann es auch ohne machen.

In welchen Fällen würde er aufs Inlinen verzichten? Und wäre eine gesparte Kopieoperation der klassische Fall wo ein Compiler sich entschließt eine Funktion trotzdem zu inlinen?

Trap
2007-11-19, 12:24:04
Die Kopie zu eliminieren wird durch die sogenannte "named return value optimization" erledigt. Die meisten modernen Compiler unterstützen das.

Gast
2007-11-19, 12:35:41
Danke. :)

Unterstützt dies auch VS2003 (mit einem Großteil Optimierungen auf off)? Würde man mit dem inlinen da das Gleiche erreichen?

Gast
2007-11-19, 12:47:32
Wenn dieses Beispiel (http://www.informit.com/articles/article.aspx?p=25033&seqNum=3&rl=1) korrekt funktioniert, tut es das leider nicht - auch nicht mit allen Optimierungen an.

Trap
2007-11-19, 13:00:55
Inline sollte, wenn es tatsächlich durchgeführt wird, auch funktionieren. Ich hab aber keine Ahnung ob man VS2003 so einstellen kann, dass es inline Funktionen auch immer inline compiliert.

Gast
2007-11-19, 15:07:14
Man kann wählen unter "Standard", "nur __inline" und "Alles Geeignete".

In welchen Fällen würde er denn verzichten eine inline Funktion direkt einzubauen?

len
2007-11-20, 15:59:06
Betrifft auch das Kopieren ... kann ich beim Überladen eines operators irgendwie auf den Speicher referenzieren anstatt zu kopieren wie im Beispiel?

struct TestStruct
{
int i;
int j;

TestStruct( int ti = 0, int tj = 0 ) : i(ti), j(tj) {};
TestStruct operator-( const TestStru& op ) const
{
return TestStruct( i - op.i, j - op.j );
};
};
besten dank.

Neomi
2007-11-20, 16:45:22
Betrifft auch das Kopieren ... kann ich beim Überladen eines operators irgendwie auf den Speicher referenzieren anstatt zu kopieren wie im Beispiel?

Solche Kopien zu verhindern, ist Aufgabe des Compilers, genau wie fast alle anderen Taktzyklen-Optimierungen auch. Wenn du da auf "kreative" Art versuchst, z.B. eine Referenz statt ein Objekt zurückzugeben, stellst du dich nur vor Probleme. Das Objekt wird nämlich nach der Konstruktion auf dem Stack (aus logischer Sicht, der Compiler macht das dank Named Return Value Optimization effizienter) wieder gelöscht, wenn die Funktion zurückkehrt, die Referenz ist dann ungültig und kann beliebige andere Daten enthalten.

Gast
2007-11-21, 07:44:53
Nee, ich meinte keine obskuren Tricks, sondern evtl. dafür vorgesehene Sprachmitteln, die ich einfach nicht kenne.

Also z.B. sowas (gerade ausgedacht):

void operator-( TestStru& returnvalue, const TestStru& op ) const
{
return TestStruct( i - op.i, j - op.j );
};

Allerdings wenn es keinen anderen Weg gibt, dann sind die Chancen ja auch recht gut, daß der Compiler diesen Weg optimiert. danke

Gast
2007-11-21, 07:46:19
meinte natürlich..

void operator-( TestStru& returnvalue, const TestStru& op ) const
{
returnvalue.i =- op.i;
returnvalue.j =- op.j;
};

Neomi
2007-11-21, 11:52:28
Das wäre keine gute Idee, das so zu schreiben, überladene Operatoren sollten sich schon erwartungsgemäß verhalten. Bei einem binären Minus solltest du einfach zwei konstante Referenzen als Parameter übergeben, nur eine bei unärem Minus. Dazu einfach ein Rückgabewert mit dem Typ der STruktur, den Rest macht jeder anständige Compiler.