2015-02-05 8 views
6

यह POD structs containing constant member जैसा लगता है, लेकिन उलट की तरह।यूनियन युक्त अस्थिर structs

#include <iostream> 

struct A 
{ 
    int a; 
}; 

union U 
{ 
    volatile A a; 
    long b; 
}; 

int main() 
{ 
    U u1; 
    U u2; 

    u1.a.a = 12; 
    u2 = u1; 
    std::cout << u2.a.a << std::endl; 

    return 0; 
} 

जी ++ 4.8.3 त्रुटि के बिना इस कोड को संकलित करता है और इसे सही ढंग से चलता है:

$ g++ -std=c++03 a.cpp -o a_gcc 
$ ./a_gcc 
12 

लेकिन बजना ++ 3.5.1 (मैं मैन्युअल रूप से कोड बॉक्स रखने के लिए त्रुटि संदेश लपेटा है एक त्रुटि पैदा करता है स्क्रॉलिंग):

$ clang++ -std=c++03 a.cpp -o a_clang 
a.cpp:8:7: error: member function 'operator=' not viable: 'this' 
argument has type 'volatile A', but function is not marked volatile 
union U 
    ^
a.cpp:3:8: note: 'operator=' declared here 
struct A 
    ^
a.cpp:20:5: note: implicit copy assignment operator for 'U' first 
required here 
     u2 = u1; 
     ^
1 error generated. 

क्या सी ++ 03 प्रोग्राम को अस्थिर structs युक्त संघ को प्रतिलिपि करने की अनुमति देता है? मुझे सी ++ 03 मानक में कुछ भी नहीं मिला जो संघ के डिफ़ॉल्ट प्रतिलिपि को परिभाषित करता है।

मैं जानना चाहता हूं कि कौन सा कंपाइलर सही है या मानक उस बिंदु पर स्पष्ट नहीं है।

संपादित करें: मुझे पता चला कि अगर मैं कॉपी असाइनमेंट के बजाय प्रतिलिपि निर्माण का उपयोग करता हूं तो दोनों clang ++ और g ++ त्रुटि के बिना प्रोग्राम संकलित करेंगे। विशेष रूप से अगर मैं main बदल होने के लिए:

int main() 
{ 
    U u1; 

    u1.a.a = 12; 
    U u2 = u1; 
    std::cout << u2.a.a << std::endl; 

    return 0; 
} 

.. तो यह काम करेंगे। मुझे आश्चर्य है कि क्यों वे clang ++ द्वारा अलग तरीके से इलाज किया जाता है।

+0

क्या होगा यदि आप 'यूनियन यू' में उपयोगकर्ता द्वारा परिभाषित असाइनमेंट ऑपरेटर जोड़ते हैं: 'अस्थिर यू और ऑपरेटर = (कॉन्स्ट अस्थिर यू &) अस्थिर'? या शायद उनमें से कुछ 'अस्थिर' के साथ? –

+0

संघ के सदस्यों को अस्थिर होने की बजाय यूनियन अस्थिरता के उदाहरण क्यों नहीं बनाते? इस तरह के व्यवहार के बारे में कारण बनाना आसान लगता है। – BlamKiwi

+0

@ जॉनजविनक क्योंकि तब यह इस समस्या का कारण नहीं बन जाएगा। – qbt937

उत्तर

0

सी ++ 11 में, यूनियन की कॉपी कन्स्ट्रक्टर को हटाया जा सकता है। हम N4140 में में [class.union] एक नोट से यह देख, §9.5:

[नोट: एक संघ के किसी भी गैर स्थैतिक डेटा सदस्य एक गैर तुच्छ डिफ़ॉल्ट निर्माता नहीं हैं (12.1) , प्रतिलिपि कन्स्ट्रक्टर (12.8), कन्स्ट्रक्टर (12.8), कॉपी असाइनमेंट ऑपरेटर (12.8), असाइनमेंट ऑपरेटर (12.8), या विनाशक (12.4) ले जाएं, संबंधित यूनियन के सदस्य फ़ंक्शन उपयोगकर्ता द्वारा प्रदत्त होना चाहिए या यह होगा संघ के लिए पूरी तरह से हटाया जाना चाहिए (8.4.3)। अंत टिप्पणी]

और [class.copy] में, §12.8/25, हम देखते हैं कि हमारे union एक गैर तुच्छ प्रतिलिपि निर्माता है:

एक प्रति/स्थानांतरित असाइनमेंट ऑपरेटर कक्षा X के लिए यह छोटा है यदि यह उपयोगकर्ता द्वारा प्रदत्त नहीं है, तो इसकी पैरामीटर-प्रकार-सूची एक अंतर्निहित घोषणा की पैरामीटर-प्रकार-सूची के समतुल्य है, और यदि ...
- [..]
- कक्षा एक्स में अस्थिर-योग्य प्रकार के गैर-स्थैतिक डेटा सदस्य हैं, और

लेकिन [class.copy] में उस विशेष लाइन उसके बाद ही पहले Is a volatile-qualified type really a POD? का एक परिणाम जोड़ा गया है, इस तरह के एक वर्ग अभी भी एक छोटी सी प्रतिलिपि निर्माता के लिए विचार किया जाएगा।

तो यह मेरी समझ है कि सी ++ 03 में, इस बात का कोई संकेत नहीं है कि संघ की प्रतिलिपि निर्माता को हटाया जाना चाहिए, और सी ++ 11 में, इसका कुछ संकेत है लेकिन यह गैर-मानक है।

+0

ध्यान दें कि आपके द्वारा उद्धृत नियम वास्तव में लागू नहीं होता है, क्योंकि यह संघ ही है जिसका प्रति-कार्य ऑपरेटर गैर-तुच्छ है, लेकिन नियम सदस्यों के लिए ऑपरेटरों के बारे में बात करता है ... और 'कक्षा ए' के ​​लिए कॉपी असाइनमेंट ऑपरेटर * तुच्छ है। –

+0

@BenVoigt एचएम। तब मुझे कुछ नहीं मिला। – Barry

+0

मुझे लगता है कि यह अभी भी मूल्यवान है, लेकिन निश्चित रूप से गैर-मानक है। –

संबंधित मुद्दे