2017-04-05 14 views
12

इस का उपयोग करते हुए इस बारे में एन-वें सवाल है, लेकिन मैं सटीक नकल कर सकता है नहीं मिल ...एक struct के सकल आरंभीकरण, अपने स्वयं के डेटा सदस्यों

मान लीजिए निम्नलिखित कोड:

#include <iostream> 

struct S { 
    int x; 
    int y; 
}; 

class C { 
public: 
    S s; 
    C() : s{123, s.x} {} 
}; 

int main() { 
    std::cout << C().s.y << '\n'; 
} 

क्या यह s.y प्रारंभ करने के लिए ठीक है? (केवल JetBrains 'ReSharper इसके बारे में शिकायत करता है: Object member this->s.x might not be initialized)।

कोई अच्छा होगा अगर कोई मानक से उद्धरण के साथ अपना उत्तर पुष्टि करता है।

+0

[निकटतम नियम] (http://eel.is/c++draft/special#class.cdtor-1) मुझे इस तरह की चीज के बारे में पता है, यहां लागू नहीं होता है, क्योंकि 'एस' मामूली है। फिर, [यह नियम] (http: // eel।है/C++ ड्राफ्ट/dcl.init.aggr # 3) आपके पक्ष में प्रतीत होता है। – WhiZTiM

+0

संबंधित [क्या यह प्रारंभिक सदस्य को प्रारंभिक प्रारंभिकरण के दौरान बाद के सदस्य अभिव्यक्ति से संदर्भित करने के लिए परिभाषित व्यवहार है?] (Http://stackoverflow.com/q/32940847/1708801) –

उत्तर

1

सी ++ 14

8.5.1 से समुच्चय [dcl.init.aggr]

1 एक कुल एक सरणी या एक वर्ग (धारा 9) कोई उपयोगकर्ता द्वारा प्रदान की कंस्ट्रक्टर्स साथ (12.1) है , कोई निजी या सुरक्षित गैर स्थैतिक डेटा सदस्यों (क्लॉज 11), कोई आधार वर्ग (क्लॉज 10), और कोई वर्चुअल फ़ंक्शन (10.3) संरक्षित नहीं है।

2 जब 8.58 में निर्दिष्ट अनुसार प्रारंभकर्ता सूची द्वारा कुल मिलाकर प्रारंभ किया जाता है, तो आरंभकर्ता सूची के तत्वों को कुल मिलाकर, सदस्यता या सदस्य आदेश में वृद्धि के लिए प्रारंभकर्ता के रूप में लिया जाता है।

इसका मतलब है कि एसएक्स को पहले 123 के साथ शुरू किया गया है, तो एस.ई. को एसएक्स के साथ शुरू किया गया है।

अनुकूलन के बिना, जीसीसी 6,3

C::C(): 
     push rbp 
     mov  rbp, rsp 
     mov  QWORD PTR [rbp-8], rdi 
     mov  rax, QWORD PTR [rbp-8] # read address of s 
     mov  DWORD PTR [rax], 123 # write 123 to s.x (offset 0 from s) 
     mov  rax, QWORD PTR [rbp-8] # read address of s again 
     mov  edx, DWORD PTR [rax] # read contents of s.x to edx 
     mov  rax, QWORD PTR [rbp-8] # read address of s 
     mov  DWORD PTR [rax+4], edx # write s.y (offset 4 from s) 
     nop 
     pop  rbp 
     ret 

कौन क्या मानकों का कहना है के साथ सहमत हैं उत्पन्न करता है।

+0

और अनुकूलन के साथ क्या? – WhiZTiM

+0

ऑप्टिमाइज़ेशन के साथ, अधिकांश कोड को हटाकर हटा दिया जाता है और परिणाम बहुत अधिक है "std :: cout << 123 << '\ n'; –

+1

कि वे * ले गए * प्रारंभिक के रूप में * जरूरी नहीं है कि प्रारंभिकरण एक ही क्रम में भी किया जाता है। मानक का यह हिस्सा कहता है कि संकलक को 'x' और 'y' के क्रम का सम्मान करना चाहिए क्योंकि वे संरचना की परिभाषा (" सदस्य क्रम में बढ़ते हुए ") में दिखाई देते हैं। एक कंपाइलर असल में कोड किसी भी भाषा-वकील प्रश्न के लिए उपयुक्त प्रमाण नहीं है। यदि मानक वास्तव में प्रारंभिकरण के एक विशिष्ट क्रम को अनिवार्य करता है, तो उसे कहीं और कहना चाहिए। –

1

हालांकि ऐसा लगता है कि ऐसा कोई नियम नहीं है जो स्पष्ट रूप से कहता है कि यह चाल खराब है, यह एक अच्छी तरह से परिभाषित व्यवहार के लिए पर्याप्त नहीं है।

मुझे लगता है कि मूल्यांकन के आदेश के साथ कुछ मुद्दे हैं:

this rule braced सूची में भाव के लिए मूल्यांकन के क्रम को परिभाषित करता है; बेशक, सदस्य प्रारंभिकरण के लिए भी एक आदेश है।

यह कहना सुरक्षित है कि प्रत्येक संरचना सदस्य को ब्रैकेट सूची में इसी अभिव्यक्ति के मूल्यांकन के बाद शुरू किया जाता है (स्पष्ट रूप से प्रारंभ करने से पहले s.x का मूल्यांकन किया जाता है)।

हालांकि ऐसा कोई नियम नहीं है जो बताएगा कि आपके मामले में s.x ब्रसेड सूची के दूसरे तत्व का मूल्यांकन करने से पहले शुरू किया जाना चाहिए, उदा। कार्यक्रम संरचना क्षेत्रों को शुरू करने से पहले ब्रैकेट सूची में सभी अभिव्यक्तियों का मूल्यांकन कर सकता है।

बेशक, नियम की अनुपस्थिति साबित करना आसान नहीं है, लेकिन यदि यह नहीं है, तो यह यूबी जैसा दिखता है।

यूपीडी: the rule from @PaulFloyd's answer वास्तव में मेरे उत्तर में क्या लापता था जैसा दिखता है, शायद यह सब के बाद यूबी नहीं है।

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