Std :: launder का उद्देश्य क्या है?


242

P0137 फ़ंक्शन टेम्प्लेट का परिचय std::launderदेता है और यूनियनों, जीवनकाल और पॉइंटर्स से संबंधित अनुभागों में मानक में कई, कई बदलाव करता है।

इस पेपर को हल करने में क्या समस्या है? जिस भाषा से मुझे अवगत होना है, उसमें क्या बदलाव हैं? और हम क्या कर रहे launderहैं?


2
क्या आप खुद पेपर के बारे में पूछ रहे हैं या इसके बारे में std::launder? std::launderइसका उपयोग "एक ऑब्जेक्ट के लिए एक पॉइंटर को प्राप्त करने के लिए किया जाता है, जो एक ही प्रकार के मौजूदा ऑब्जेक्ट द्वारा कब्जा किए गए स्टोरेज में बनाया गया है, भले ही इसमें कॉन्स्टेंट या संदर्भ सदस्य हों।"
txtechhelp

7
विषय पर उपयोगी लिंक । इसके अलावा यह सवाल stackoverflow.com/questions/27003727/…
पॉल रूनी

यह अब VC2017 में संस्करण 15.7.0
डेमियन

एसटीडी के अनुसार, संकेत तुच्छ प्रकार हैं इसलिए लॉंडर कुछ भी नहीं करता है। ;)
जिज्ञासु

जवाबों:


250

std::launderउपयुक्त नाम है, हालांकि केवल अगर आप जानते हैं कि यह किस लिए है। यह मेमोरी लॉन्ड्रिंग करता है ।

कागज में उदाहरण पर विचार करें:

struct X { const int n; };
union U { X x; float f; };
...

U u = {{ 1 }};

यह कथन कुल मिलाकर प्रारंभिक प्रदर्शन करता है, के Uसाथ पहले सदस्य को आरंभ करता है {1}

क्योंकि nएक है constचर, संकलक ग्रहण करने के लिए है कि नि: शुल्क है u.x.nजाएगा हमेशा 1 हो।

यदि हम ऐसा करते हैं तो क्या होता है:

X *p = new (&u.x) X {2};

क्योंकि Xतुच्छ है, हमें इसकी जगह एक नया बनाने से पहले पुरानी वस्तु को नष्ट करने की आवश्यकता नहीं है, इसलिए यह पूरी तरह से कानूनी कोड है। नई वस्तु का nसदस्य 2 होगा।

तो बताओ ... क्या u.x.nलौटाएगा?

स्पष्ट उत्तर 2 होगा। लेकिन यह गलत है, क्योंकि संकलक को यह मानने की अनुमति है कि वास्तव में constचर (न कि केवल एक const&, लेकिन घोषित वस्तु चर const) कभी नहीं बदलेगा । लेकिन हमने इसे बदल दिया।

[basic.life] / 8 उन परिस्थितियों को बाहर निकालता है जब पुराने बनाए गए चर / बिंदुओं / संदर्भों के माध्यम से नव निर्मित वस्तु तक पहुंचना ठीक होता है। और constसदस्य होना अयोग्य कारकों में से एक है।

तो ... हम कैसे u.x.nठीक से बात कर सकते हैं ?

हमें अपनी याददाश्त बढ़ानी होगी:

assert(*std::launder(&u.x.n) == 2); //Will be true.

मनी लॉन्ड्रिंग का उपयोग लोगों को ट्रेस करने से रोकने के लिए किया जाता है जहां आपको अपना पैसा मिला था। मेमोरी लॉन्ड्रिंग का उपयोग कंपाइलर को ट्रेसिंग से रोकने के लिए किया जाता है जहां आपको अपनी वस्तु मिली थी, इस प्रकार इसे किसी भी अनुकूलन से बचने के लिए मजबूर करना जो अब लागू नहीं हो सकता है।

अयोग्य कारकों में से एक है यदि आप ऑब्जेक्ट के प्रकार को बदलते हैं। std::launderयहाँ भी मदद कर सकते हैं:

aligned_storage<sizeof(int), alignof(int)>::type data;
new(&data) int;
int *p = std::launder(reinterpret_cast<int*>(&data));

[basic.life] / 8 हमें बताता है कि, यदि आप पुराने के भंडारण में एक नई वस्तु आवंटित करते हैं, तो आप पुराने के लिए पॉइंटर्स के माध्यम से नई वस्तु तक नहीं पहुँच सकते। launderहमें उस ओर कदम बढ़ाने की अनुमति देता है।


34
तो क्या मेरा tl? Dr सही है: "लॉन्ड्रिंग मूल रूप से गैर-यूबी प्रकार के चालाक के लिए है"?
ड्रैकुर्ली

13
क्या आप बता सकते हैं कि यह सच क्यों है? "क्योंकि nएक constचर है, संकलक मानने के लिए स्वतंत्र है कि u.x.nहमेशा 1 होगा।" मानक में यह कहां कहा गया है? मैं पूछता हूं क्योंकि आपने जो समस्या बताई है, वह मुझे इस बात का आभास कराएगा कि यह पहली जगह में गलत है। यह केवल as-if नियम के तहत सही होना चाहिए, जो यहां विफल रहता है। मैं क्या खो रहा हूँ?
user541686

10
@ मेहरदाद [basic.life] / 8: " यदि, [...] भंडारण स्थान पर एक नई वस्तु बनाई जाती है, जिस पर मूल वस्तु का कब्जा होता है [...] मूल वस्तु का नाम स्वचालित रूप से नई वस्तु को संदर्भित करेगा। [...] अगर: [...] प्रकार [...] में कोई भी गैर-स्थैतिक डेटा सदस्य नहीं है, जिसका प्रकार
कॉन्स्टेबल

14
@ बेरी वेरी; यदि पते पर स्थित टाइप टी की कोई वस्तु नहीं है ptr, तो आप launderपूर्व शर्त तोड़ देते हैं , इसलिए परिणाम के बारे में बात करने का कोई मतलब नहीं है।
टीसी

17
@ एनकोलबोलस एक ही उम्मीद कर सकता है कि सुपरकैट समितियों की उतनी ही पैरवी करे जितना वे एसओ पर साथी तीसरे पक्ष के भाषा उपयोगकर्ताओं से जवाब मांगने में करते हैं। इसके अलावा, एक अच्छा अनुकूलन संकलक के अपने सही समाधान अनुकूलित करेंगे memcpyएक में जगह पुनर्व्याख्या में समर्थित (यानी ढीला संरेखण) प्लेटफॉर्म पर वैसे भी
अंडरस्कोर_ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.