c - प्रिंटफ़ के साथ डबल ब्रैकेट का उपयोग करते समय विभाजन गलती




linux segmentation-fault (2)

#include<stdio.h>
#define POOLNAME_FMT "Hello"

void main() {

 printf((POOLNAME_FMT "Cannot allocate %d bytes" POOLNAME_FMT "in pool not enough memory",5));

}

जब मैं printf साथ डबल ब्रैकेट का उपयोग करता हूं तो यह विभाजन गलती क्यों देता है यानी printf(( )); ?


आप इसे एहसास किए बिना अल्पविराम ऑपरेटर का उपयोग कर रहे हैं:

( ... "in pool not enough memory",5)
                                 ^

चूंकि अल्पविराम ऑपरेटर अपने बाएं ऑपरेंड का मूल्यांकन करेगा और परिणाम को त्याग देगा और फिर मूल्यांकन करेगा और सही ऑपरेंड वापस करेगा, आप इसके साथ समाप्त होगा:

printf( 5 ) ;

जो प्रारूप स्ट्रिंग के लिए एक int const char *restrict को एक const char *restrict परिवर्तित करने का प्रयास करेगा, जो निश्चित रूप से मान्य स्मृति को इंगित नहीं करेगा () बिना, यह , फ़ंक्शन तर्कों के लिए सिर्फ एक विभाजक रहा होगा।

इस संदर्भ में () एक अभिव्यक्ति है; यदि हम सीएमए ड्राफ्ट मानक अनुभाग 6.5.1 प्राथमिक अभिव्यक्तियों को देखते हैं, तो हमारे पास:

( expression )

इसलिए , एक ऑपरेटर के रूप में माना जाता है , जबकि हम खंड 6.5.2 से देख सकते हैं। पोस्टफिक्स ऑपरेटर्स :

postfix-expression ( argument-expression-listopt )
argument-expression-list:
   assignment-expression
   argument-expression-list , assignment-expression
                            ^

यह फ़ंक्शन कॉल में केवल एक विभाजक है।

सक्षम होने वाले चेतावनियों को यहां मदद करनी चाहिए, gcc मुझे इस कार्यक्रम के लिए कुछ चेतावनियां देती है:

चेतावनी: कॉमा अभिव्यक्ति के बाएं हाथ के प्रचालन का कोई असर नहीं है [-वियोग-मान]

तथा

चेतावनी: '' printf '' का तर्क 1 गुणा करता है, बिना किसी कलाकार के पूर्णांक से संकेत करता है [डिफ़ॉल्ट रूप से सक्षम] नोट: अपेक्षित 'const char * restrict', लेकिन तर्क 'int' प्रकार है


इसका कारण यह है कि printf एक फ़ंक्शन है, जो एक एकल कोष्ठक में अपनी तर्क को स्वीकार करेगा, और दूसरे कोष्ठकों का दूसरा सेट वास्तव में एक उप-एक्सप्रेशन खोल रहा है:

(string "string" string "string" , 5)

पहले चार तार को संकलन के समय में एकत्रित किया जाता है, उपज:

("string", 5)

इसके बाद इसका मूल्यांकन किया जाता है:

  • "string" इसके पहले अक्षर के लिए एक सूचक को मूल्यांकन करता है
  • , बी पहले मूल्यांकन करता है, फिर परिणाम निकाल देता है, फिर मूल्यांकन करता है और रिटर्न बी
  • 5 एक पूर्णांक निरंतर 5 को मूल्यांकन करता है

वास्तव में, आप कॉल कर रहे हैं:

printf(5);

(इसका कारण यह है कि स्ट्रिंग का कोई साइड इफेक्ट नहीं है।)

ऐसा कुछ, हालांकि, काम करेगा:

printf((POOLNAME_FMT "Cannot allocate %d bytes" POOLNAME_FMT "in pool not enough memory"),5);

नोट करें कि कैसे अल्पविराम और पांच को कोष्ठकों से अलग subexpression के बाहर ले जाया गया।





comma-operator