सी ++ 20 के बाद से आवंटित भंडारण पर सूचक अंकगणित की अनुमति है?


10

C ++ 20 मानक में, यह कहा जाता है कि सरणी प्रकार अंतर्निहित जीवनकाल प्रकार हैं

क्या इसका मतलब यह है कि गैर-निहित जीवनकाल प्रकार के लिए एक सरणी को अंतर्निहित रूप से बनाया जा सकता है? इस तरह की एक सरणी के निहित निर्माण से सरणी के तत्वों का निर्माण नहीं होगा?

इस मामले पर विचार करें:

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (which object?)
std::string * sptr = std::launder(static_cast<std::string*>(ptr));
//pointer arithmetic on not created array elements well defined?
new (sptr+1) std::string("second element");

क्या यह कोड C ++ 20 के बाद से UB नहीं है?


शायद यह तरीका बेहतर है?

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to the array of 10 std::string" 
std::string (* sptr)[10] = std::launder(static_cast<std::string(*)[10]>(ptr));
//pointer arithmetic on an array is well defined
new (*sptr+1) std::string("second element");

1
मैंने अभी (ड्राफ्ट) C ++ 20 मानक के माध्यम से एक खोज की है, और कुछ भी नहीं मिला है जो सरणियों को "निहित जीवनकाल प्रकार" के रूप में वर्णित करता है (और, हां, मैंने विविधताएं खोजी हैं)। कृपया अपने दावे का अधिक विस्तृत विवरण प्रदान करें (जैसे मानक में खंड और खंड)। स्रोत खोजने में सक्षम होने के बिना अपने प्रश्न का उत्तर देने के लिए थोड़ा कठिन है, अकेले किसी भी प्रासंगिक संदर्भ को दें।
पीटर

1
@Peter: eel.is/c++draft/basic.types#9 , अंतिम वाक्य
गेज़ा

मैं पीडीएफ को देख रहा था- open.std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf (जाहिरा तौर पर नवीनतम वर्किंग ड्राफ्ट) और इसमें वह वाक्य भी नहीं है। लगता है कि आपको "निहित-जीवनकाल" का अर्थ खोजने की आवश्यकता होगी। मुझे संदेह है कि आपके लिंक ने कुछ "एडिट्स इन प्रोग्रेस" को उठाया हो सकता है जिसने इसे जारी किए गए ड्राफ्ट में भी नहीं बनाया है।
पीटर

1
@ पेटर बदलाव हालिया प्राग बैठक से P0593 के मानक में विलय होने के परिणाम हैं । उन्होंने अभी तक परिणामी मसौदे को अभी तक जारी नहीं किया है, लेकिन आप इस प्रतिबद्ध में विलय को देख सकते हैं ।
अखरोट

जवाबों:


3

क्या इसका मतलब है कि गैर-निहित जीवनकाल प्रकार के लिए एक सरणी को अंतर्निहित रूप से बनाया जा सकता है?

हाँ।

इस तरह की एक सरणी के निहित निर्माण से सरणी के तत्वों का निर्माण नहीं होगा?

हाँ।

यह वह है जो std::vectorसाधारण C ++ में लागू करने योग्य बनाता है।


क्या आप यह भी पुष्टि कर सकते हैं कि std::launder(static_cast<std::string*>(ptr))सरणी के पहले तत्व के लिए एक पॉइंटर नहीं लौटाता क्योंकि यह उसके जीवनकाल के भीतर नहीं है, लेकिन यह std::launder(static_cast<std::string(*)[10]>(ptr))एक पॉइंटर को सरणी में लौटाता है, क्योंकि सरणी अपने जीवनकाल के भीतर है?
ओलिव

यह मुझे सही लगता है।
टीसी

@Oliv और मुझे लगता std::launderहै कि वास्तव में जरूरत नहीं है, क्योंकि eel.is/c++draft/intro.object#11 गारंटी देता है कि ptrपहले से ही सरणी को इंगित करेगा?
अखरोट

@ ग्वाला, मुझे याद किया। एक तो static_castकरने के लिए std::string (*) [10]पर्याप्त होना चाहिए! tx।
ओलिव

@Oliv लेकिन मुझे लगता है कि सवाल यह है कि क्या std::launderइच्छाशक्ति के बिना आपका पहला उदाहरण अच्छी तरह से परिभाषित होगा। std::stringइंगित करने के लिए कोई वस्तु नहीं है, लेकिन ptrसरणी को इंगित कर सकता है, जिससे कि स्थिर कलाकार मान को अपरिवर्तित छोड़ sptrदेगा और साथ ही सरणी को इंगित करेगा। इसके साथ std::launderबस यूबी की std::launderआवश्यकताओं के कारण है।
अखरोट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.