Warum diese Warnung vom IBM XL C / C ++ - Compiler?

8

Hier ist ein Beispiel für einen minimalen Code, das das Problem veranschaulicht:

%Vor%

Dies ergibt denselben Fehler:

%Vor%

IBM XL C / C ++ 8.0-Compiler unter AIX gibt diese Warnungen aus:

%Vor%

Ich habe auch g ++ 4.1.2 mit "-Wall" und "-pedantic" ausprobiert und keine Diagnose bekommen. Warum ist hier der Zugriff auf den Kopierkonstruktor erforderlich? Wie kann ich die Warnung eliminieren, abgesehen davon, dass das Objekt kopierbar ist (was außerhalb meiner Kontrolle liegt) oder eine explizite Kopie erstellt werden muss (wenn das reale Objekt teuer zu kopieren ist)?

    
Fred Larson 23.10.2009, 20:15
quelle

4 Antworten

9

Die Regeln hierfür sind in §8.5.3 / 5 der Norm. Es gibt drei grundlegende Situationen. Die erste beinhaltet den Initialisierer ('3' in Ihrem Fall), der entweder ein L-Wert oder ein Klassentyp ist. Da keiner von beiden wahr ist, ist das, was Sie haben, der dritte Fall: Initialisieren einer Konst-Referenz mit einem R-Wert, der keinen Klassentyp hat. Dieser Fall ist in der letzten Aufzählung in 8.5.3 / 5 enthalten:

Andernfalls wird ein temporäres Objekt vom Typ "cv1 T1" erstellt und anhand des Initialisierungsausdrucks initialisiert, wobei die Regeln für eine Initialisierung ohne Referenzkopie (8.5) verwendet werden. Die Referenz ist dann an das Temporäre gebunden. Wenn T1 Bezug zu T2 hat, muss cv1 dieselbe cv-Qualifikation wie cv2 oder eine höhere cv-Qualifikation sein als cv2; Ansonsten ist das Programm schlecht ausgebildet.

Bearbeiten: nochmal lesen, ich denke IBM hat es richtig gemacht. Ich habe vorher über die Möglichkeit nachgedacht, das Temporäre kopieren zu müssen, aber das ist nicht die Ursache des Problems. Um die temporäre Initialisierung mit Nicht-Referenzkopie wie in § 8.5 beschrieben zu erstellen, benötigt sie die Kopie ctor. Insbesondere entspricht es an dieser Stelle einem Ausdruck wie:

T x = a;

Dies entspricht im Wesentlichen:

T x = T (a);

i.e. Es ist erforderlich, ein temporäres Objekt zu erstellen und dann das temporäre Element in das zu initialisierende Objekt zu kopieren (in diesem Fall ist auch ein temporäres Objekt). Um den erforderlichen Prozess zusammenzufassen, entspricht er in etwa dem Code:

%Vor%     
Jerry Coffin 23.10.2009, 20:50
quelle
3

C ++ erlaubt hinreichend intelligenten Compilern, das Kopieren temporärer Objekte zu vermeiden, eine Verletzung der as-if -Regel, die der Standard zulässt. Ich bin nicht vertraut mit IBM AIX C ++ - Compiler, aber es klingt wie es denkt, der show(3) Aufruf erfordert eine temporäre Sache zu kopieren. In diesem Fall erfordert C ++, dass Sie einen barrierefreien Kopierkonstruktor haben, obwohl Ihr Compiler schlau genug ist, um ihn zu vermeiden.

Aber warum benötigt show(3) überhaupt eine Kopie? Das kann ich nicht herausfinden. Mit etwas Glück wird Litb ein bisschen mitkommen.

    
David Seiler 23.10.2009 20:26
quelle
1

Mein Bauchgefühl ist, dass Jerrys Antwort ist richtig, aber es gibt noch ein paar Fragen.

Interessant ist, dass es einen Kernpunkt gibt, der den vorherigen Abschnitt dieses Abschnitts abdeckt ( 391 ). Dieses Problem betrifft, wenn das Argument derselbe Klassentyp ist. Speziell:

%Vor%

Die Änderung im Kernproblem 391 wirkt sich nur auf den rvalue aus temporär hat denselben Klassentyp. Der vorherige Wortlaut hatte:

  

Wenn der Initialisierungsausdruck ein R-Wert ist, mit T2 ein Klassentyp und cv1 T1 mit cv2 T2, referenzkompatibel ist, wird die Referenz wie folgt gebunden:

     

[...]

     

Der Konstruktor, der zum Erstellen der Kopie verwendet wird, muss aufrufbar sein, unabhängig davon, ob die Kopie tatsächlich erstellt wurde oder nicht.

Diese letzte Zeile ist, was show(Thing(3)) gemäß dem aktuellen Standard illegal machen würde. Der vorgeschlagene Wortlaut für diesen Abschnitt lautet:

  

Wenn der Initialisierungsausdruck ein R-Wert ist, mit T2 ein Klassentyp und "cv1 T1" mit "cv2 T2" referenzkompatibel ist, ist die Referenz an das Objekt gebunden, das durch den rvalue repräsentiert wird (siehe 3.10 [basic.lval ]) oder zu einem Unterobjekt innerhalb dieses Objekts.

An dieser Stelle dachte ich, dass g ++ möglicherweise sein Verhalten gemäß aktualisiert hat 391 , aber die Änderung beinhaltete versehentlich den Initialisierungsfall. Dies wird jedoch von den Versionen von g ++, mit denen ich getestet habe, nicht demonstriert:

%Vor%

Ich kann keinen Fehler in Jerrys Interpretation für den foo (3) -Fall finden, aber ich habe Zweifel wegen der Diskrepanz zwischen den verschiedenen Compiler-Verhalten.

    
Richard Corden 26.10.2009 13:15
quelle
0

Was passiert, wenn Sie versuchen, das temporäre Ding zu benennen?

Thing temp(3);
show(temp);

    
user200783 23.10.2009 20:41
quelle

Tags und Links