2016-08-08 33 views
3

Garantiert Standard C++ 11, dass alle 3 temporären Objekte vor Beginn der Funktion erstellt wurden?Gewährleistet Standard C++ 11, dass temporäre Objekte, die an eine Funktion übergeben werden, vor dem Funktionsaufruf erstellt wurden?

Auch wenn temporäre Objekt übergeben, wie:

  1. Objekt
  2. rvalue Verweis
  3. bestanden nur Mitglied der temporären Objekt

http://ideone.com/EV0hSP

#include <iostream> 
using namespace std; 

struct T { 
    T() { std::cout << "T created \n"; } 
    int val = 0; 
    ~T() { std::cout << "T destroyed \n"; } 
}; 

void function(T t_obj, T &&t, int &&val) { 
    std::cout << "func-start \n"; 
    std::cout << t_obj.val << ", " << t.val << ", " << val << std::endl; 
    std::cout << "func-end \n"; 
} 

int main() { 

    function(T(), T(), T().val); 

    return 0; 
} 

Ausgang:

T created 
T created 
T created 
func-start 
0, 0, 0 
func-end 
T destroyed 
T destroyed 
T destroyed 

Working Draft, Standard für Programmiersprache C++ 2016.07.12: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

§ 5.2.2 Funktionsaufruf

§ 5.2.2

1 A Funktionsaufruf ist ein Postfix Ausdruck gefolgt von Klammern, die eine möglicherweise leere, Komma-getrennte Liste von Initialisierer-Klauseln enthalten, die diebildenArgumente für die Funktion.

Aber kann jeder von T erstellt nach func-Start?

Oder gibt es eine Möglichkeit, Argumente als g/r/l/x/pr-Wert zu übergeben, damit die Funktion gestartet wird, bevor das temporäre Objekt erstellt wird?

enter image description here

+0

Ich verstehe die Frage nicht. Wie könnte eine Funktion überhaupt von Nutzen sein, wenn ihre Argumente zu der Zeit, als ihr Körper zu wirken begann, noch nicht existierten? –

+0

@underscore_d In C++ kann es nicht sein, was im Standard klar beschrieben ist. Aber wenn es nicht im Standard beschrieben wurde, dann: ** 1. ** 'function()' kann inline sein. ** 2. ** Das Objekt kann bei der ersten Verwendung dieses Objekts erstellt werden, auch nach einem Code aus der Funktion - weil der Compiler jede Operation neu anordnen kann, wenn sie sich nicht ändert. Observable-Verhalten (hat keine Ein-/Ausgabe, Speicher-Zäune, ...) - ** § 1.9 Programmausführung 1, 5, 8 **. Zitat: "Der Compiler kann Anweisungen und Operationen frei nach Belieben neu ordnen." http://StackOverflow.com/Questions/30606924/Can-Function-Calls-be-ordered – Alex

+0

Richtig, # 2 hilft mir zu verstehen und macht das zu einem guten Punkt, der durch die Anforderung für die Sequenzierung ausgeschlossen scheint. Ich warte immer noch auf C++, um eine native Syntax für lazy initialisierte Objekte zu bekommen ... Über # 1 bin ich sicher, dass es immer noch inline sein könnte, oder? nur der Compiler müsste zuerst die 3 Argumente erzeugen (unbestimmt untereinander sequenziert) und diese speichern, um sie im Inline-Körper zu verwenden. –

Antwort

11

[intro.execution]/16:

Wenn eine Funktion aufgerufen wird (ob oder ob nicht die Funktion inline ist), jeder Wertberechnung und Nebenwirkungen, die mit jedem Argument Ausdruck oder mit dem Postfix-Ausdruck, der die genannte Funktion Bezeichnen , wird vor der Ausführung jedes Ausdrucks oder Anweisung im Körper der aufgerufenen Funktion sequenziert.

7

Von [expr.call]/8 haben wir

[Hinweis: Die Bewertungen der Postfix-Ausdruck und der Argumente sind alle unsequenced relativ zueinander. Alle Nebeneffekte von Argumentauswertungen werden vor der Eingabe der Funktion sequenziert (siehe 1.9). -ende note]

Das bedeutet, dass alle Parameter vor der Eingabe der Funktion erstellt werden.

Dies garantiert auch, dass alle Parameter nach dem Verlassen der Funktion zerstört werden.