c++ - Std:: launder का उद्देश्य क्या है?
memory c++17 (1)
std::launder
aptly नाम है, हालांकि केवल अगर आप जानते हैं कि यह किस लिए है।
यह
मेमोरी लॉन्ड्रिंग
करता है।
कागज में उदाहरण पर विचार करें:
struct X { const int n; };
union U { X x; float f; };
...
U u = {{ 1 }};
यह कथन कुल मिलाकर प्रारंभिक प्रदर्शन करता है,
U
के पहले सदस्य को
{1}
साथ आरंभ करता है।
क्योंकि
n
एक
uxn
चर है, इसलिए संकलक यह मानने के लिए स्वतंत्र है कि
uxn
हमेशा
1 होगा।
यदि हम ऐसा करते हैं तो क्या होता है:
X *p = new (&u.x) X {2};
क्योंकि
X
तुच्छ है, हमें इसकी जगह एक नया बनाने से पहले पुरानी वस्तु को नष्ट करने की आवश्यकता नहीं है, इसलिए यह पूरी तरह से कानूनी कोड है।
नई वस्तु का अपना
n
सदस्य 2 होगा।
तो बताइए ...
uxn
क्या लौटेगा?
स्पष्ट उत्तर 2 होगा। लेकिन यह गलत है, क्योंकि कंपाइलर को यह मानने की अनुमति है कि वास्तव में एक
const
वैरिएबल (केवल एक
const&
नहीं है, लेकिन एक ऑब्जेक्ट वैरिएबल
घोषित
const
)
कभी नहीं बदलेगा
।
लेकिन हमने इसे बदल दिया।
[basic.life]/8
उन परिस्थितियों से बाहर निकलता है जब पुराने बनाए गए चर / बिंदुओं / संदर्भों के माध्यम से नव निर्मित वस्तु तक पहुंचना ठीक होता है।
और एक
const
सदस्य होने से अयोग्य कारकों में से एक है।
तो ... हम
uxn
बारे में
uxn
ठीक से बात कर सकते हैं?
हमें अपनी याददाश्त बढ़ानी होगी:
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
हमें उस ओर कदम
launder
अनुमति देता है।