सवाल जीसीसी मानक शीर्षकों में इतने सारे कोष्ठक


जीसीसी हेडर फाइलों में लगातार अभिव्यक्ति क्यों हैं, इस तरह से ब्रांड्स से घिरा हुआ है?

#define INTMAX_MIN (-9223372036854775807LL)
#define INTMAX_MAX (9223372036854775807LL)

यदि मैं ब्रांड्स को छोड़ देता हूं तो इस तरह का अंतर क्या होगा?

#define INTMAX_MIN -9223372036854775807LL
#define INTMAX_MAX 9223372036854775807LL

और 'एल' प्रत्यय क्यों है? अगर मैं निम्नलिखित लिखूं तो क्या यह वही होगा?

#define INTMAX_MIN -9223372036854775807
#define INTMAX_MAX 9223372036854775807

क्या कोई वास्तविक उपयोगिता है या क्या यह हमेशा एक ही चीज़ है?

मुझे पता है कि 'एल' लंबे समय तक खड़ा है और मैं सी मैक्रोज़ में कोष्ठक के महत्व के बारे में भी अच्छी तरह से अवगत हूं; मैं जिज्ञासा के लिए यह पूछ रहा हूँ।


44
2017-12-27 02:19


मूल




जवाब:


अगर आपने लिखा था

a = 7 INTMAX_MIN;

आप एक वाक्यविन्यास त्रुटि प्राप्त करने की उम्मीद करेंगे, क्योंकि इसके चेहरे पर यह एक अवैध अभिव्यक्ति होगी। और यह होगा, क्योंकि यह फैलता है

a = 7 (-9223372036854775807LL);

जो वास्तव में आपको एक वाक्यविन्यास त्रुटि देता है। लेकिन बिना किसी कोष्ठक के यह विस्तारित होगा:

a = 7 -9223372036854775807LL;

जो आपको स्पष्ट रूप से नहीं होने के बावजूद आपको एक त्रुटि नहीं देता है।

अधिक आम तौर पर, ये सभी परिभाषित चीजों के लिए विस्तार देते हैं जो पहचानकर्ताओं की तरह दिखते हैं। एक अंकगणितीय अभिव्यक्ति में, एक पहचानकर्ता "प्राथमिक अभिव्यक्ति" है, लेकिन -9223372036854775807 एलएल नहीं है। हालांकि, एक संश्लेषित अभिव्यक्ति एक "प्राथमिक अभिव्यक्ति" है।

और यह असली कारण है। ताकि मैक्रो क्या फैलता है की तरह लगता है कुछ ऐसा करने के लिए एक प्राथमिक अभिव्यक्ति है एक प्राथमिक अभिव्यक्ति। क्या होता है आप कभी आश्चर्यचकित नहीं होंगे। प्रोग्रामिंग में, आश्चर्य आमतौर पर बुरा होता है।

आम तौर पर इससे कोई फर्क नहीं पड़ता, लेकिन परिभाषित करने वाले लोग नहीं चाहते हैं कि वे आम तौर पर काम करें। वे चाहते हैं कि वे हमेशा काम करें।

पिछला एलएल इस पूर्णांक को शाब्दिक प्रकार के रूप में चिह्नित करता है long long, जो आम तौर पर (और इस मामले में) 64 बिट्स है। एलएल प्रत्यय के बिना, शाब्दिक को int, long int, या long long int के रूप में व्याख्या किया जा सकता है, जो भी 64-बिट मानों का समर्थन करने वाला पहला व्यक्ति है। इस प्रकार को कम करना मूल्य के आधार पर उतना ही महत्वपूर्ण हो सकता है।


84
2017-12-27 02:39



आप भी चर्चा कर सकते हैं a = 7-INT_MAX; चारों ओर कोष्ठक के साथ और बिना INT_MAX, यह नोट करते हुए कि परिणाम अलग होगा a = 7 - INT_MAX;। - Jonathan Leffler
@ जोनाथन लेफ्लर परिणाम कैसे अलग होगा? आपको के लिए कोष्ठक की आवश्यकता नहीं होनी चाहिए INT_MAX चूंकि एक पूर्णांक शाब्दिक प्राथमिक अभिव्यक्ति है। - Eric M Schmidt
@EricMSchmidt: ... ब्लाह, ब्लाह ...  ... जब तक ... ओह ड्रैट! मूल अलग प्रीप्रोसेसर प्रक्रिया एक जवाब देने के लिए प्रतिबद्ध थी, लेकिन आधुनिक (1 9 8 9 या बाद में) संस्करण इनपुट को टोकनकृत करता है और इनपुट टोकनकृत रहता है, इसलिए #define X -7 तथा int main(void) { int x = 7-X; return x; } एक कार्यक्रम उत्पन्न करता है जो स्थिति 14 के साथ निकलता है। मुझे याद रखना चाहिए था। - Jonathan Leffler
"शाब्दिक को सामान्य पूर्णांक के रूप में व्याख्या किया जाएगा" @ mafso टिप्पणियों के रूप में गलत है। प्रयत्न printf("%zu\n", sizeof (9223372036854775807)); - chux
@ माफसो: यह भाषा के दृष्टिकोण से बिल्कुल सही नहीं है। सी भाषा का एकमात्र मानक संस्करण जिसका उपयोग करने की अनुमति है अहस्ताक्षरित प्रत्यय-कम स्थिरांक के प्रकार C89 / 90 था। यह कार्यक्षमता सी 99 में अवैध थी। प्रत्यय-कम स्थिरांक केवल हो सकता है पर हस्ताक्षर किए प्रकार के। यदि निरंतर सबसे बड़े हस्ताक्षरित प्रकार में फिट नहीं होता है तो व्यवहार अपरिभाषित होता है। अर्थात। भाषा का उपयोग करने का समर्थन नहीं करता है unsigned long long एक प्रत्यय कम स्थिर के लिए। - AnT


एक पूर्णांक स्थिरांक और इस तरह के एक यूनरी ऑपरेटर के साथ एक मैक्रो पर कोष्ठक डालने के लिए यह एक अच्छा अभ्यास है:

#define BLA (-1)

यूनरी ऑपरेटरों के रूप में (- यहां) सी में उच्चतम प्राथमिकता नहीं है। पोस्टफिक्स ऑपरेटरों के पास यूनरी ऑपरेटरों की तुलना में अधिक प्राथमिकता है। याद रखें कि सी में नकारात्मक स्थिरांक नहीं हैं, उदाहरण के लिए -1 के साथ एक निरंतर अभिव्यक्ति है - यूनरी ऑपरेटर।

एक तरफ पीसी-लिंट इस तरह के मैक्रोज़ में ब्रांड्स का सुझाव देता है:

(नियम 9 73): अभिभावक # परिभाषित एन (-1)   मैक्रो 'प्रतीक' में यूनरी ऑपरेटर कोष्ठक नहीं - एक यूनरी   एक अभिव्यक्ति की तरह मैक्रो में दिखाई देने वाला ऑपरेटर को संश्लेषित नहीं किया गया था। के लिये   उदाहरण:

#define N -1

उपयोगकर्ता ऐसी चीजों को संश्लेषित करना पसंद कर सकता है:

#define N (-1)

19
2017-12-27 02:33





यह जवाब दिखाने का प्रयास क्यों करता है LL जरूरत है। (यह आसान नहीं है।)
अन्य उत्तरों ने दिखाया है कि ब्रांड्स की आवश्यकता क्यों है।

आइए तीन मैक्रोज़ कोड करें, सब कुछ हैं दशमलव स्थिरांक

#define MAXILL (9223372036854775807LL)
#define MAXIL  (9223372036854775807L)
#define MAXI   (9223372036854775807)

भले ही MAXI इसमें कोई प्रत्यय नहीं है, जो इसे टाइप नहीं करता है intMAXI पहले प्रकार में यह फिट होगा, या तो int, long, long longया एक विस्तारित पूर्णांक प्रकार।

भले ही MAXIL है L प्रत्यय, यह पहला प्रकार होगा जिसमें यह फिट बैठता है, या तो long, long longया एक विस्तारित पूर्णांक प्रकार।

भले ही MAXILL है LL प्रत्यय, यह पहला प्रकार होगा जिसमें यह फिट बैठता है, या तो long longया एक विस्तारित पूर्णांक प्रकार।

हर मामले में, मैक्रोज़ का वही मान होता है, लेकिन संभावित विभिन्न प्रकार।

प्रकार निर्धारण के लिए C11dr §6.4.4.1 5 देखें।


आइए उन्हें प्रिंट करने का प्रयास करें और करें int तथा long 32-बिट हैं और long long तथा intmax_t 64 हैं

printf("I   %d %d %d",       MAXI, MAXIL, MAXILL);    //Error: type mismatch
printf("LI  %ld %ld %ld",    MAXI, MAXIL, MAXILL);    //Error: type mismatch
printf("LLI %lld %lld %lld", MAXI, MAXIL, MAXILL);    //Ok

आखिरी पंक्ति में सभी तीन सही हैं क्योंकि सभी तीन मैक्रोज़ हैं long long, पिछले प्रारूप में प्रारूप विनिर्देशक और संख्या के बीच गलत-मिलान प्रकार हैं।

अगर हमारे पास है int 32-बिट है और long, long long तथा intmax_t 64 हैं, तो निम्नलिखित सही हैं।

printf("LI  %ld %ld",    MAXI, MAXIL);
printf("LLI %lld", MAXILL);

अधिकतम चौड़ाई पूर्णांक प्रकार का एक प्रारूप विनिर्देशक है "%" PRIdMAX। यह मैक्रो विस्तार नहीं कर सकता है "%ld"  तथा  "%lld" सुविधा देना MAXI, MAXIL, MAXILL। यह तय है "%lld" और संबंधित संख्याएं intmax_t एक ही प्रकार की आवश्यकता है। इस मामले में, long long और केवल फॉर्म MAXILL इस्तेमाल किया जाना चाहिए।


अन्य कार्यान्वयन में एक विस्तारित पूर्णांक प्रकार हो सकता है (जैसे int128_t), इस मामले में एक कार्यान्वयन विशिष्ट प्रत्यय या कुछ तंत्र का उपयोग किया जा सकता है।


13
2017-12-27 07:23



एक नोट के रूप में, सी 11 के साथ _Generic (और लोकप्रिय के साथ पहले typeof विस्तार) प्रकार आसान देखने योग्य हो गए हैं। (एक्सटेंशन के बिना सी 99 में, मुझे नहीं पता कि बीच का अंतर कैसा है long तथा long long देखा जा सकता है कि उनके पास समान आकार और प्रतिनिधित्व है; यह देखते हुए कि यह ठीक है अगर कार्यान्वयन सम्मेलनों को कॉल करने के बारे में धारणा करता है, और यह कि यह काफी संभावना नहीं है long तथा long long अलग-अलग पारित किए जाते हैं, सवाल यह है कि सख्त सी 99 के लिए प्रत्यय वास्तव में जरूरी है।) - mafso