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
ফিরবে?
সুস্পষ্ট উত্তরটি ২ হবে But তবে এটি ভুল, কারণ সংকলকটিকে ধরে নেওয়া যায় যে সত্যিকারের const
পরিবর্তনশীল (কেবলমাত্র একটি নয় const&
, তবে একটি অবজেক্ট ভেরিয়েবল ঘোষিত const
) কখনই পরিবর্তিত হবে না । তবে আমরা কেবল এটি পরিবর্তন করেছি।
[বেসিক.লাইফ] / 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));
[বেসিক.লাইফ] / 8 আমাদের বলছে যে, আপনি যদি পুরনোটির স্টোরেজে কোনও নতুন অবজেক্ট বরাদ্দ করেন তবে আপনি পুরানো পয়েন্টারের মাধ্যমে নতুন অবজেক্টে অ্যাক্সেস করতে পারবেন না। launder
আমাদের পার্শ্ব-পদক্ষেপ করতে দেয়।
std::launder
?std::launder
"একই ধরণের বিদ্যমান অবজেক্টের দ্বারা দখলকৃত স্টোরেজে নির্মিত কোনও সামগ্রীর পয়েন্টার অর্জন করতে ব্যবহৃত হয়, যদিও এতে কনস্ট বা রেফারেন্স সদস্য থাকলেও।"