2012-08-03 12 views
10

मैं विरासत कोड से जीसीसी चेतावनियों को हटा रहा हूं।कैसे हल करें: "कोड में अलग-अलग आकार के पूर्णांक से पॉइंटर पर डालें" चेतावनी?

example: 

some_struct *ptr = func() // func() returns an integer. 

कोई मुझे मार्गदर्शन कृपया कैसे इस तरह के जीसीसी चेतावनियों को सुलझाने के लिए कर सकते हैं:

यह चेतावनी typecasting के माध्यम से "अलग अलग आकार के पूर्णांक से सूचक के साथ ढाले" को दबाने के लिए संभव है?

+7

आप एक संरचना सूचक में एक पूर्णांक क्यों रखना चाहते हैं? – Jay

+0

यह संभव है, लेकिन जिन मामलों में यह जाने का सही तरीका है दुर्लभ हैं। –

+0

"आउटपुट" differencies के अधिभार है? (इनपुट पैरामीटर नहीं) –

उत्तर

19

सबसे पहले, यदि आप func (इसके स्रोत को संशोधित करने की अनुमति है) को ठीक कर सकते हैं, तो इसे ठीक करें। यदि इसकी गणना पॉइंटर्स के साथ की जा सकती है, तो उन्हें पॉइंटर्स और रिटर्न पॉइंटर्स के साथ करें। कभी-कभी पते के साथ पूर्णांक के रूप में काम करने के वैध कारण होते हैं (उदाहरण के लिए, विशेष कोड में संरेखण के मुद्दों से निपटना)। उस स्थिति में, uintptr_t प्रकार (stdint.h में परिभाषित) का उपयोग करने के लिए func बदलें। यह आवश्यक होने पर पॉइंटर्स को पूर्णांक के रूप में इलाज के लिए डिज़ाइन किया गया है। (intptr_t भी है यदि हस्ताक्षर किए गए अंकगणित किसी कारण से बेहतर है, लेकिन मुझे आमतौर पर कम परेशानी होने के लिए हस्ताक्षर किए गए uintptr_t मिलते हैं।) पसंदीदा रूप से, func को uintptr_t को लौटने पर पॉइंटर में कनवर्ट करना चाहिए, इसलिए func का रिटर्न प्रकार एक पॉइंटर होगा (कुछ, शायद some_struct या void)।

यदि आप func को ठीक नहीं कर सकते हैं, तो आप उस कंपाइलर को बताने के लिए कह सकते हैं कि आप किए जा रहे रूपांतरणों का इरादा रखते हैं। हालांकि, यह विशेष त्रुटि संदेश आपको बता रहा है कि आप केवल एक सूचक को पूर्णांक में परिवर्तित नहीं कर रहे हैं, लेकिन आप एक आकार (उदा।, चार बाइट्स) के एक पूर्णांक को दूसरे आकार के सूचक (उदाहरण के लिए, आठ बाइट्स) में परिवर्तित कर रहे हैं। ऐसा लगता है कि यह कोड मूल रूप से एक सिस्टम के लिए लिखा गया था जहां func द्वारा पूर्णांक प्रकार का आयाम सूचक आकार के समान आकार था, लेकिन अब आप उस सिस्टम पर संकलन कर रहे हैं जहां सूचक प्रकार उस पूर्णांक आकार से बड़ा या कम है।

उस स्थिति में, आपको यह सुनिश्चित करना होगा कि func द्वारा की गई गणना नई वास्तुकला में काम करती है। यदि यह केवल 32-बिट मान लौटा रहा है, तो क्या वह हमेशा सही मान रखेगा? यही है, लापता उच्च 32 बिट्स से कुछ भी खो जाएगा? कोई पता नहीं है कि func गणना करना चाहिए कि यह कभी भी पूर्णांक प्रकार के अधिकतम मान से अधिक है? यदि func हस्ताक्षरित पूर्णांक प्रकारों का उपयोग कर रहा है, तो साइन बिट पर भी विचार करें।

यदि आपने यह सुनिश्चित किया है कि func द्वारा लौटाया गया मूल्य सही है, तो आप स्पष्ट कारणों का उपयोग कर सकते हैं, जैसे: some_struct *ptr = (some_struct *) (intptr_t) func();

6

मेरा जीसीसी आपके द्वारा उद्धृत चेतावनी नहीं देता है। यह भी अजीब होगा क्योंकि आपके कोड में कोई कलाकार नहीं है।

मैं चेतावनी मिलती है

assignment makes pointer from integer without a cast 

नोट "एक डाली के बिना" भाग। इस प्रकार आप (व्यवहार को बदलने के बिना) कास्टिंग द्वारा जीसीसी चुप कर सकते हैं: फिर

some_struct *ptr = (void*)func(); 

, आप अपने चेतावनी ("अलग अलग आकार के पूर्णांक से सूचक को कास्ट") func की वापसी प्रकार iff मिल फिट नहीं करता होगा पते के लिए। इसे func() को एक उपयुक्त पूर्णांक प्रकार के साथ कास्टिंग करके चुप किया जा सकता है, उदा। intptr_t:

some_struct *ptr = (void*)(intptr_t)func(); 
यह सब इस धारणा क्या तुम सच में एक सूचक को गलत आकार पूर्णांक कनवर्ट करना चाहते हैं के तहत

। शायद, कोड को फिर से काम करना एक बेहतर विचार है।

3

वहाँ दो संभावनाएं यहां हैं:

  1. func एक पूर्णांक के लिए एक वास्तविक सूचक कास्टिंग है; इसे बाद में एक सूचक के रूप में उपयोग किया जाता है।
  2. func एक पूर्णांक लौटा रहा है जो एक सूचक में संग्रहीत किया जा रहा है; ptr बाद में एक पूर्णांक में डाला गया है और एक पूर्णांक के रूप में उपयोग किया जाता है।

पहले मामले में, func से वापसी मान जानकारी खो देंगे, और संभावित दुर्घटना या बुरा, अगर int एक डेटा सूचक का आकार है, जो यह हो जाएगा सबसे पर 64-bit memory models (सहित विंडोज से छोटा होता है और लिनक्स)। उस स्थिति में आपको func से intptr_t का रिटर्न प्रकार बदलना चाहिए; Using intptr_t instead of void*? और Why/when to use `intptr_t` for type-casting in C? देखें।

दूसरे मामले में, यह एक समस्या से कम है, लेकिन intptr_t: some_struct *ptr = (some_struct *)(intptr_t)func(); और बाद में int value = (int)(intptr_t)ptr; के माध्यम से आपको उन्मूलन समस्याओं से निपटने के लिए एक समस्या है। इस मुद्दे की चर्चा के लिए GLib Type Conversion Macros देखें।

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