2014-12-29 8 views
5

जो मैं अनुभव कर रहा हूं वह मेरे हस्ताक्षर किए गए चार सूचक को हस्ताक्षरित चार पॉइंटर पर डालने के लिए मेरे कंपाइलर से इनकार करना है। मैं थोड़ी देर के लिए उलझन में आया, क्योंकि मैं सबसे लंबे समय के लिए हस्ताक्षर बदलने के लिए static_cast का उपयोग कर रहा था।'कॉन्स्टेटेड char * const *' से 'const constigned char * const *' से static_cast की अनुमति नहीं है

फिर मैंने थोड़ा खुदाई की (ठीक है, यह बहुत गहरा नहीं था। मैंने थोड़ा सा स्कूपिंग किया था!) ​​और फिर भी मैं समझता हूं कि static_cast द्वारा पॉइंटर प्रकार कास्टिंग की रोकथाम यही कारण है कि यह सुरक्षित है और कास्ट करने का बेहतर तरीका (पारंपरिक विकल्पों की तुलना में जो कार्यान्वयन परिभाषित व्यवहार या अपरिभाषित व्यवहार का आह्वान कर सकते हैं), मुझे अभी भी यकीन नहीं है कि मुझे वास्तव में मेरी स्थिति के लिए क्या करना चाहिए।

क्या मैं यहाँ है एक ओपन एपीआई समारोह जिनके हस्ताक्षर

void glShaderSource(
    GLuint shader, GLsizei count, const GLchar **string, const GLint *length 
); 

है ताकि बजाय एक char * के रूप में डेटा एक फ़ाइल से पढ़ने लौटने का, मैं क्या मैं हाल ही में फ़ाइल पाठक एपीआई बदल के लिए एक कॉल है अब यह unsigned char * के साथ है। यह परिवर्तन गलती से नहीं किया गया था क्योंकि मुझे लगता है कि एक हस्ताक्षरित चार कच्चे डेटा के लिए एक बेहतर संभाल है (भले ही यह एएससीआईआई डेटा भी हो), और वास्तव में void * इस संबंध में और भी स्पष्ट हो सकता है।

और फिर निश्चित रूप से मैं glShaderSource पर तीसरे तर्क के रूप में इस सूचक का पता पारित कर दूंगा।

मुझे लगता है कि सी-स्टाइल कास्ट सिर्फ GLchar** पर करना सुरक्षित है, और वास्तव में यह शायद इस स्थिति के लिए मानक उत्तर है। reinterpret_cast का उपयोग केवल ऊपर और परे जा रहा है, लेकिन स्वीकार्य रूप से केवल एक छोटी राशि से।

लेकिन मैं शायद इस स्थिति में विचार प्रक्रिया के बारे में कुछ और जानना चाहूंगा। क्यों यह बिल्कुल ठीक है कि मैं यहां हिस्सेदारी पर हस्ताक्षर की हस्ताक्षर को खारिज करने में सक्षम हूं? क्या यह बस इतना है कि जब से मैं कभी भी ऐसे शेडर को लिखने की उम्मीद नहीं करता जिसके पास उसके किसी भी चरित्र पर उच्च सेट सेट है जिसका अर्थ है कि मैं इसे कास्ट कर सकता हूं?

क्या होगा यदि मुझे हस्ताक्षरित/हस्ताक्षरित पूर्णांक वाले किसी स्थिति का सामना करना पड़ रहा है, और वास्तव में नकली नकारात्मक पूर्णांक मानों के बड़े सकारात्मक मूल्यों के रूप में व्याख्या किए जाने के गंभीर परिणाम हैं? इसके बारे में "सुरक्षित" होने का प्रयास करने के लिए मैं यहां कोड कैसे लिख सकता हूं?

मेरी वृत्ति मुझे बता रही है कि वास्तव में यह कोड लागू किए बिना स्पष्ट रूप से असंभव है और पॉइंटर को पारित करने के बजाय डेटा को स्वयं देखता है, इसलिए इस स्थिति में static_cast की सुरक्षा हासिल करने का कोई तरीका नहीं है, क्योंकि मैं ' मुझे पॉइंटर्स के साथ काम करने के लिए मजबूर किया जा रहा है।

+0

आपका प्रश्न क्या है? आपको 'static_cast (p)' लिखने की अनुमति क्यों नहीं है, जब 'p'' char * 'है? आप केवल हस्ताक्षरित से हस्ताक्षरित या इसके विपरीत में कनवर्ट नहीं कर रहे हैं, आप * पुन: व्याख्या कर रहे हैं * पॉइंटर क्या इंगित करता है। – Praetorian

+0

तो आप कह रहे हैं कि मैं जो वास्तविक ऑपरेशन कर रहा हूं वह वास्तव में एक वास्तविक पुनरावृत्ति ऑपरेशन है, इसलिए 'reinterpret_cast' का उपयोग करने के लिए वास्तविक सही चीज है? –

+0

आपका अंतिम पैराग्राफ सी ++ प्रश्न की तुलना में अधिक ग्ले-प्रश्न प्रतीत होता है, जो कि इस सवाल पर कोई ग्लो-संबंधित टैग नहीं है, जो थोड़ा अजीब है। क्या वह जानबूझकर था? – WhozCraig

उत्तर

7

आपको reinterpret_cast का उपयोग करने की आवश्यकता है ताकि char * और unsigned char * के बीच भी परिवर्तित हो सके। (के साथ या बिना)। ऐसा इसलिए है क्योंकि आप अलग-अलग प्रकार के बिट्स के रूप में एक प्रकार के रूप में संग्रहीत बिट्स का इलाज कर रहे हैं; जबकि static_cast मूल्य रूपांतरण करने के लिए है।

रूप WhozCraig बताते हैं, char ** और unsigned char ** के बीच परिवर्तित वास्तव में एक और सूचक प्रकार (हां, तो भी reinterpret_cast की आवश्यकता होती है) के रूप में एक सूचक aliasing है।

यह सब सिद्धांत में एक समस्या हो सकती है, लेकिन व्यावहारिक विचारों (आईएमओ) के संदर्भ में, सभी संभावनाओं का समर्थन करने के लिए आपको जिस प्रयास की आवश्यकता है, वह बहुत ही परेशानी है; सभी उद्देश्यों और उद्देश्यों के लिए आप मान सकते हैं कि charunsigned char के रूप में एलआईज़िंग मान रूपांतरणों के समान परिणाम देता है, और इसी तरह दो सूचक प्रकारों के लिए।

unsigned char* src = ...; // your input 
char* srcChar = static_cast<char*>(static_cast<void*>(src)); 
glShaderSource(..., &src, ...); 

मैं यह नहीं कहूंगा कि यह एक reinterpret_cast से अच्छे है, लेकिन कम से कम यह पता चलता है कि एक reinterpret_cast सख्ती से आवश्यक नहीं है:

+1

सही है, लेकिन उन प्रकारों को फिर से परिभाषित नहीं किया जा रहा है। संकेत की एक अतिरिक्त परत है (जो थोड़ी सी में पुन: व्याख्या करने की आवश्यकता को बदलती नहीं है)। – WhozCraig

+0

यहां मेरे मामले के लिए कोड है जो 'glShaderSource (हैंडल, 1, reinterpret_cast (& source), sourcelen) को संकलित करता है; ' –

+0

तो, जबकि यह * तकनीकी रूप से * कार्यान्वयन-परिभाषित व्यवहार है, हम उचित रूप से आश्वस्त हो सकते हैं जब तक कि मैं एक * लंबे * समय के लिए वास्तव में वास्तव में अलग-अलग वास्तुकला के लिए बंदरगाह नहीं करता, कि मैं इस अपेक्षित व्यवहार –

1

आप अगर आप एक void* मध्यवर्ती का उपयोग पूरी तरह से static_cast साथ रूपांतरण कर सकते हैं।

+0

नोट: यदि 'reinterpret_cast' किसी विशेष कार्यान्वयन पर काम नहीं करता है तो यह –

+0

काम नहीं करेगा इस जादूगर की smacks। इसके बजाय इसका उपयोग न करें जब तक कि यह कुछ वास्तविक लाभ प्रदान न करे। लेकिन, यह निश्चित रूप से एक साफ चाल है। –

+0

@StevenLu ठीक है, आप 'static_cast' के साथ समाधान मांग रहे थे। ;) हालांकि मैं दावा नहीं करता कि यह सुंदर है, मुझे लगता है कि यह दिलचस्प है कि 'static_cast' को 'reinterpret_cast' से अधिक सुरक्षित माना जाता है, लेकिन इस मामले में, आप एक ही static_cast' के साथ ऐसा ही कर सकते हैं जहां अधिकतर लोग 'reinterpret_cast' का उपयोग करेंगे। –

संबंधित मुद्दे