2017-08-24 17 views
10

AIX'de xlC ile aşağıdakileri derlemek, "2 2" yi basan bir kodla sonuçlanır. Linux'ta gcc ve clang ile güvenilir şekilde "3 3" üretir. AIX combine dönüş değerine RVO uyguluyor gibiRVO'nun geri dönüşten önceki parametrede üzerine yazma değeri

#include <iostream> 

struct Numbers 
{ 
    Numbers() : a(0) , b(0) { } 
    Numbers(int a, int b) : a(a), b(b) { } 

    int a; 
    int b; 
}; 

Numbers combine(const Numbers& a, const Numbers& b) 
{ 
    Numbers x; 
    x.a = a.a + b.a; 
    x.b = a.b + b.b; 
    return x; 
} 

Numbers make() 
{ 
    Numbers a(1, 1); 
    Numbers b(2, 2); 

    a = combine(a, b); 
    return a; 
} 

int main() 
{ 
    Numbers a = make(); 
    std::cerr << a.a << " " << a.b << "\n"; 
} 

bana görünüyor, bu yüzden Numbers x oluştururken, varsayılan x başlatılmak ile benim parametresini a üzerine yazarak biter.

Burada tanımlanmamış bazı davranışları çağırıyorum mu? acombine(a, b)'un değerlendirilip a'a atanmasına kadar hiçbir değişiklik yapılmamasını beklerim.

Bu

ile geçerli: AIX için IBM XL C/C++, V12.1 (5765-J02, 5725-C72) Versiyon: 12.01.0000.0012 Bu derleyici benziyor

+6

Ben UB burada görmüyorum. Derleyici bir hata gibi görünüyor. – Jarod42

+0

Eğer "std :: cerr << a.a <<" "<< a.b <<" \ n ";' make() 'içine eklerseniz ne olur? – NathanOliver

+0

Geri dönüş birleştirmeyi (a, b); – Jarod42

cevap

3

kopya elision performans olduğunu Sadece bir başlatma işleminde bunu yapabileceği kopya atama (!). Diğer bir deyişle, derleyici, başlatılırken, a parametrenizle ilişkilendirilmiş nesnenin üzerine yazılır. RVO (RVO'nun bir tanımı için) uygulamasının combine dönüş değerine sahip olması kendi başına yanlış değildir. Yanlış olan, RVO'nun (make kapsamında geçici olması gereken ve make'da a ile ilişkili nesne olmaması) hedefidir. Geçici bir çözüm olarak çalışması gerektiğini bir kullanıcı sağlanan kopya atama operatörü ekleme

:

Numbers &operator=(const Numbers &other) { a = other.a; b = other.b; return *this; } 
İlgili konular