2011-01-12 15 views
5

मैं http://www.gnu.org/s/libc/manual/html_node/Argument-Macros.html#Argument-Macrosस्व बढ़ावा देना डेटा प्रकार

पर सी में variadic फ़ंक्शन का उपयोग करने के लिए विधि के माध्यम से पढ़ने हालांकि, मैं स्वयं को बढ़ावा देने के डेटा प्रकार का अर्थ समझ में असमर्थ था। वे & वे गैर-आत्म-प्रचार डेटा प्रकारों से अलग कैसे हैं?

उत्तर

4

यहां C99 standard है; "आत्म-प्रचार" प्रकार वे हैं जो डिफ़ॉल्ट तर्क प्रचार (§6.5.2.2 अनुच्छेद 6, §6.3.1.1 में वर्णित पूर्णांक पदोन्नति का संदर्भ देने) के लिए स्वयं को बढ़ावा देते हैं।

va_arg परिभाषा (§7.15.1.1) की मेरी पढ़ाई यह है कि यह सीमा मानक द्वारा निहित है। प्रासंगिकता का पैरा 2 में है:

[...] या यदि प्रकार (के रूप में डिफ़ॉल्ट तर्क प्रोन्नति के लिए अनुसार पदोन्नत) नहीं वास्तविक अगले तर्क के प्रकार के साथ संगत है [... ]

जो वास्तविक अगले तर्क के प्रकार के बारे में प्रचारित किया जा रहा काफी स्पष्ट है, लेकिन मैं के रूप में यह नहीं कह पढ़ें कुछ भी के बारे में प्रकार प्रचारित किया जा रहा। (मुझे लगता है कि "(प्रचारित ...)" खंड केवल एक अनुस्मारक है कि जब एक varargs फ़ंक्शन कहा जाता है तो ट्रेलिंग तर्कों पर डिफ़ॉल्ट तर्क प्रचार किया जाता है।)

यह आइटम § में अपरिभाषित व्यवहार की सूची में है J.2 इस पढ़ने का समर्थन करता है:

- जब वहाँ कोई वास्तविक अगले तर्क है, या एक निर्दिष्ट प्रकार है कि वास्तविक अगले तर्क के पदोन्नत प्रकार के साथ संगत नहीं है, कुछ के साथ साथ va_arg मैक्रो शुरू हो जाती है अपवाद (7.15.1.1)।

(हालांकि हाँ, मुझे पता है, अनुलग्नक जे "मानक" के बजाय "जानकारीपूर्ण" है ...)।

जो मामले में: va_arg(ap, float) (उदाहरण के लिए) मान्य नहीं हो सकता है - उस मामले में प्रकारfloat है, लेकिन वास्तविक अगले तर्क की पदोन्नत प्रकार संभवतः नहीं हो सकता float (एक float तर्क double करने के लिए प्रोत्साहित किया जाता था)।

+0

क्या इस प्रतिबंध के लिए कोई विशेष कारण है? शायद 'va_arg' अपूर्णता के साथ कुछ करने के लिए? –

+1

@ क्रिप्टो: मुझे संदेह है कि जैक सही है (जेन्स को उसकी प्रतिक्रिया देखें); अनुपालन से विशेष सहायता के बिना किसी दिए गए प्रकार के डिफ़ॉल्ट तर्क पदोन्नति को खोजने का कोई स्पष्ट तरीका नहीं है, इसलिए यह 'va_arg (ap, type)' के कार्यान्वयन की अनुमति देता है जो ऐसी सहायता के बिना काम करता है। (उदाहरण के लिए 'एपी' में स्टैक पर वर्तमान तर्क के लिए बाइट पॉइंटर रखें; फिर 'va_arg' कुछ भयानक मैक्रो हो सकता है जो कि' टाइप * 'के लिए कास्टिंग करके अगले तर्क पर जाता है,' टाइप * 'पॉइंटर को बढ़ाता है, और एक बाइट पॉइंटर को वापस कास्टिंग।) –

2

यह एक ग्लिब प्रतिबंध है, सी मानक में ऐसा नहीं है।

इसके पीछे विचार यह है कि पूर्णांक प्रकार है कि तथाकथित "रूपांतरण रैंक" है int की तुलना में छोटे स्वचालित रूप से signed या unsignedint करने के लिए प्रोत्साहित कर रहे हैं। एक va_arg समारोह तो इस तरह के एक व्यापक तर्क पाता है। va_arg मैक्रो को पहले int प्रकार के व्यापक तर्क को पढ़ना चाहिए, और फिर इसे मूल प्रकार पर वापस डालना चाहिए।

(एक ही double को float w.r.t के लिए आयोजित करता है।)

अनजान प्रोग्रामर इस आश्चर्यजनक परिणाम हो सकता है के लिए, तो मैं विचार है कि इस से बचा जाना चाहिए के साथ सहमत हैं। जो वर्णन आप उद्धृत कर रहे हैं, वह यह दर्शाता है कि इसे छोटे प्रकार का उपयोग न करने के लिए लगाया गया है। यह फर्जी है और जैसा कि मैंने मानक के साथ संरेखण में नहीं कहा था। दूसरी ओर यदि आप कोड लिखते हैं क्योंकि वे सुझाव देते हैं कि आपके पास पोर्टेबिलिटी समस्या कभी नहीं होगी क्योंकि यह एक प्रतिबंध है और विस्तार नहीं है।

+2

मेरे ज्ञान का सबसे अच्छा मैथ्यू सही है और आप गलत हैं; यह प्रतिबंध * कम से कम सी 99 में * है। यदि आप इसके बारे में सोचते हैं, तो यह बहुत मुश्किल होगा - मैं _impossible_ की कसम खाता नहीं हूं, लेकिन सी मानक ने आम तौर पर कार्यान्वयन पर _difficult_ आवश्यकताओं को रखने से बचा है - 'va_arg' के" पारंपरिक "कार्यान्वयन के लिए (एक जो इस संकुचन के बिना एक कंपाइलर आंतरिक में विस्तार नहीं करता है, यह देखते हुए कि तर्क प्रचार कॉलर में होता है। – zwol

+0

@Zack: मान लें कि शब्द कम से कम संदिग्ध है, "प्रचारित ..." का दायरा स्पष्ट नहीं है। लेकिन मैं आपसे सहमत नहीं हूं कि संकीर्ण प्रकारों की अनुमति के कार्यान्वयन पर * अधिक * बोझ डालता है। उन्हें केवल संकीर्ण प्रकारों की जांच करनी होगी, प्रचारित प्रकार के तर्क को पढ़ना होगा (एक कार्यान्वयन को यह जानना होगा कि उस प्रकार को कैसे ढूंढें, किसी भी तरह) और मूल्य को वापस संकीर्ण प्रकार में डालें। –

+2

यह एक कंपाइलर आंतरिक * से * करने के लिए एक आसान बात होगी। 'Va_arg' के पारंपरिक कार्यान्वयन में ऐसी किसी भी सुविधा तक पहुंच नहीं है; यह सब कुछ (तकनीकी रूप से अपरिभाषित) कोर भाषा अभिव्यक्तियों के साथ करता है। चूंकि सी में प्रकारों पर मेटाप्रोग्रामिंग करने का कोई तरीका शामिल नहीं है, इसलिए मुझे नहीं लगता कि आप केवल कोर भाषा अभिव्यक्तियों का उपयोग करके "प्रचारित प्रकार का तर्क ढूंढ सकते हैं और संकीर्ण प्रकार पर वापस आ सकते हैं"। – zwol

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