मैं निम्नलिखित कोड अपरिभाषित व्यवहार का आह्वान है कि क्या यह निर्धारित करने के कोशिश कर रहा हूँ:पुनर्व्याख्या के माध्यम से गलत संदर्भ बनाना डाली
#include <iostream>
class A;
void f(A& f)
{
char* x = reinterpret_cast<char*>(&f);
for (int i = 0; i < 5; ++i)
std::cout << x[i];
}
int main(int argc, char** argue)
{
A* a = reinterpret_cast<A*>(new char[5])
f(*a);
}
मेरे समझ है कि करने के लिए और char*
से reinterpret_cast
रों शिकायत क्योंकि मानक परमिट char
और साथ aliasing हैं unsigned char
संकेत (जोर मेरा):
तो एक कार्यक्रम othe के एक lvalue के माध्यम से एक वस्तु की संग्रहीत मूल्य का उपयोग करने का प्रयास निम्नलिखित प्रकार के व्यवहार अपरिभाषित है में से एक से r:
- वस्तु के गतिशील प्रकार,
- वस्तु के गतिशील प्रकार का एक सीवी योग्य संस्करण,
- एक प्रकार है कि हस्ताक्षर किए या ऑब्जेक्ट के गतिशील प्रकार से संबंधित हस्ताक्षरित प्रकार,
- ऑब्जेक्ट के गतिशील प्रकार के सीवी-योग्य संस्करण के साथ हस्ताक्षरित या हस्ताक्षरित प्रकार का एक प्रकार,
- एक समेकित या संघ प्रकार जिसमें एक शामिल है उपरोक्त प्रकार के सदस्यों के बीच (सहित, पुनरावर्ती, एक subaggregate या निहित संघ) के एक सदस्य,
- एक प्रकार है कि एक (संभवतः सीवी-योग्य) वस्तु के गतिशील प्रकार के आधार वर्ग प्रकार है,
- एक
char
याunsigned char
प्रकार।
हालांकि, मुझे यकीन है कि f(*a)
अमान्य सूचक के लिए एक A&
संदर्भ बनाकर अपरिभाषित व्यवहार का आह्वान है कि क्या नहीं कर रहा हूँ। निर्णायक कारक सी ++ मानक के संदर्भ में "पहुंचने का प्रयास" शब्दकोष का अर्थ है।
मेरे अंतर्ज्ञान करता है कि नहीं, एक पहुँच गठन के बाद से एक पहुँच A
की आवश्यकता होगी में परिभाषित किया जा करने के लिए (यह घोषित किया जाता है, लेकिन इस उदाहरण में परिभाषित नहीं है)। दुर्भाग्यवश, मुझे सी ++ मानक में "एक्सेस" की ठोस परिभाषा नहीं मिल रही है:
क्या f(*a)
अपरिभाषित व्यवहार का आह्वान करता है? सी ++ मानक में "पहुंच" का गठन क्या होता है?
मैं समझता हूं कि, जवाब के बावजूद, उत्पादन कोड में इस व्यवहार पर भरोसा करना एक बुरा विचार है। मैं इस प्रश्न को मुख्य रूप से भाषा की मेरी समझ में सुधार करने की इच्छा से पूछ रहा हूं।
[संपादित करें] @ सर्गेय ने मानक के इस खंड का हवाला दिया। मैं इसे यहाँ आसान संदर्भ (जोर मेरा) के लिए शामिल किया है:
5.3.1/1 [expr.unary.op]
एकल
*
ऑपरेटर अविवेक करता है: अभिव्यक्ति के लिए जो इसे लागू किया गया है किसी ऑब्जेक्ट प्रकार के लिए पॉइंटर, या किसी फ़ंक्शन प्रकार के पॉइंटर और परिणाम ऑब्जेक्ट या फ़ंक्शन का संदर्भ देने वाला एक लवल्यू है जिसमें अभिव्यक्ति बिंदुएं होती हैं।यदि अभिव्यक्ति का प्रकार "T
पर सूचक है," परिणाम का प्रकार "T
" है। [नोट: एक अपूर्ण प्रकार (सीवी शून्य के अलावा) के सूचक के माध्यम से संकेत मान्य है। इस प्रकार प्राप्त किया गया लाभा सीमित तरीकों से उपयोग किया जा सकता है (उदाहरण के लिए संदर्भ शुरू करने के लिए); यह अंतराल एक प्रसार में परिवर्तित नहीं किया जाना चाहिए, 4.1 देखें। - अंत टिप्पणी]
4,1 के संदर्भ ट्रेसिंग, हम पाते हैं:
4,1/1 [conv.lval]
एक गैर समारोह का एक glvalue (3.10) , गैर-सरणी प्रकार
T
को एक प्रसार में परिवर्तित किया जा सकता है। यदिT
एक अधूरा प्रकार है, तो एक प्रोग्राम जो इस रूपांतरण की आवश्यकता है, खराब है। यदि टी एक गैर-वर्ग प्रकार है, तो प्रक्षेपण का प्रकारT
का सीवी-अयोग्य संस्करण है। अन्यथा, प्रक्षेपण का प्रकारT
है।एक lvalue करने वाली rvalue रूपांतरण एक अभिव्यक्ति
e
को लागू किया जाता है, और या तो:
e
संभावित मूल्यांकन नहीं किया जाता है, या- एक के मूल्यांकन में की
द्वारा odr-used नहीं हैe
परिणाम मूल्यांकनe
के संभावित परिणामों के सेट के सदस्य, औरex
एक वेरिएबलx
का नाम है जोex
(3.2)में निहित मान संदर्भित ऑब्जेक्ट तक नहीं पहुंचा है।
मुझे लगता है कि हमारा उत्तर *a
दूसरे बुलेट बिंदु को संतुष्ट करता है या नहीं। मुझे उस स्थिति को पार्स करने में परेशानी हो रही है, इसलिए मुझे यकीन नहीं है।
'ए' का संरेखण क्या है? – curiousguy