'इंट मेन है?' एक मान्य C / C ++ प्रोग्राम?


113

मैं पूछता हूं क्योंकि मेरा कंपाइलर ऐसा लगता है, भले ही मैं नहीं करता।

echo 'int main;' | cc -x c - -Wall
echo 'int main;' | c++ -x c++ - -Wall

क्लैंग इस के साथ कोई चेतावनी या त्रुटि नहीं जारी करता है, और केवल मीक चेतावनी जारी करता है:, 'main' is usually a function [-Wmain]लेकिन केवल जब सी के रूप में संकलित किया जाता -std=है।

अन्यथा, यह ठीक संकलन और लिंक करता है। लेकिन निष्पादन पर, यह तुरंत SIGBUS(मेरे लिए) समाप्त हो जाता है ।

C (C) और C ++ में मुख्य () वापसी पर क्या (उत्कृष्ट) उत्तरों के माध्यम से पढ़ना ? और भाषा चश्मा के माध्यम से एक त्वरित grep, यह निश्चित रूप से मुझे लगता है कि एक मुख्य कार्य की आवश्यकता है। लेकिन gcc's -Wmain('मुख्य' आमतौर पर एक फ़ंक्शन है) और (यहाँ त्रुटियों की कमी) से क्रिया संभवत: अन्यथा सुझाव देती है।

पर क्यों? क्या इसके लिए कुछ अजीब धार वाला मामला या "ऐतिहासिक" उपयोग है? किसी को पता है क्या देता है?

मेरी बात, मुझे लगता है, क्या मुझे सच में लगता है कि यह एक मेजबान वातावरण में एक त्रुटि होनी चाहिए , एह?


6
Gcc को (अधिकतर) मानक अनुरूप संकलक बनाने के लिए आपको जरूरत हैgcc -std=c99 -pedantic ...
pmg

3
@pmg इसकी वही चेतावनी, साथ या बिना -pedanticया कोई भी -std। मेरा सिस्टम c99भी इसे बिना किसी चेतावनी या त्रुटि के संकलित करता है ...
ज्यॉफ निक्सन

3
दुर्भाग्य से, यदि आप "पर्याप्त चतुर" हैं, तो आप ऐसी चीजें बना सकते हैं जो संकलक द्वारा स्वीकार्य हैं लेकिन समझ में नहीं आती हैं। इस स्थिति में, आप C रनटाइम लाइब्रेरी को एक वैरिएबल कॉल करने के लिए लिंक कर रहे हैं main, जो काम करने की संभावना नहीं है। यदि आप "सही" मान के साथ मुख्य को इनिशियलाइज़ करते हैं, तो यह वास्तव में वापस आ सकता है ...
मैट पीटरसन 10

7
और यहां तक ​​कि अगर यह वैध है, तो यह एक भयानक बात है (अपठनीय कोड)। BTW, यह होस्ट किए गए कार्यान्वयन और फ्री-स्टैंडिंग कार्यान्वयन में भिन्न हो सकता है (जिसके बारे में नहीं पता है main)
बेसिल स्टायरनेविच

1
अधिक मज़ेदार समय के लिए, कोशिश करेंmain=195;
imallett

जवाबों:


97

चूंकि प्रश्न सी और सी ++ के रूप में दोहरा है, इसलिए सी ++ और सी के लिए तर्क अलग होगा:

  • सी ++ लिंकर को अलग-अलग प्रकार के समान रूप से समान प्रतीकों के बीच अंतर करने में मदद करने के लिए नाम प्रबंधन का उपयोग करता है, जैसे एक वैश्विक चर xyz और एक मुक्त-स्थायी वैश्विक फ़ंक्शन xyz(int)। हालांकि, नाम mainकभी भी मंगली नहीं होता है।
  • C मैनिंजिंग का उपयोग नहीं करता है, इसलिए प्रोग्राम के लिए लिंकर को भ्रमित करने के लिए एक अलग प्रतीक के स्थान पर एक प्रकार का प्रतीक प्रदान करना संभव है, और प्रोग्राम सफलतापूर्वक लिंक है।

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

यहाँ एक ही मुद्दे का एक और चित्रण है:

फ़ाइल xc:

#include <stdio.h>
int foo(); // <<== main() expects this
int main(){
    printf("%p\n", (void*)&foo);
    return 0;
}

फ़ाइल yc:

int foo; // <<== external definition supplies a symbol of a wrong kind

संकलन:

gcc x.c y.c

यह संकलन करता है, और यह संभवतः चलेगा, लेकिन यह अपरिभाषित व्यवहार है, क्योंकि संकलक को दिए गए प्रतीक का प्रकार लिंकर को आपूर्ति किए गए वास्तविक प्रतीक से अलग है।

जहां तक ​​चेतावनी जाती है, मुझे लगता है कि यह उचित है: सी आपको उन पुस्तकालयों का निर्माण करने देता है जिनका कोई mainकार्य नहीं है, इसलिए संकलक mainअन्य उपयोगों के लिए नाम को मुक्त करता है यदि आपको mainकिसी अज्ञात कारण के लिए एक चर को परिभाषित करने की आवश्यकता है ।


3
हालाँकि, C ++ कंपाइलर मुख्य फ़ंक्शन को अलग तरह से मानता है। इसका नाम बाहरी "सी" के बिना भी नहीं रखा गया है। मुझे लगता है कि ऐसा इसलिए है क्योंकि अन्यथा इसे लिंकिंग सुनिश्चित करने के लिए अपने स्वयं के बाहरी "सी" मुख्य को फेंकना होगा।
UldisK

@ युल्डिसके हां, मैंने खुद इस पर गौर किया, और काफी दिलचस्प पाया। यह समझ में आता है, लेकिन मैं उस बारे में कभी नहीं सोचा था।
ज्योफ निक्सन

2
दरअसल, सी ++ और सी के लिए परिणाम अलग नहीं हैं , जैसा कि यहां बताया गया है - mainसी ++ में नामकरण (इसलिए ऐसा लगता है) के अधीन नहीं है, चाहे वह फ़ंक्शन हो या न हो।
ज्योफ निक्सन

4
@ मुझे लगता है कि प्रश्न की आपकी व्याख्या बहुत संकीर्ण है: पोस्ट के शीर्षक में प्रश्न पूछने के अलावा, ओपी स्पष्ट रूप से इस बात की व्याख्या चाहता है कि उसका कार्यक्रम पहले स्थान पर क्यों संकलित किया गया ("मेरे संकलक को ऐसा लगता है,) भले ही मैं "नहीं" और साथ ही यह सुझाव भी देता हूं कि यह mainफ़ंक्शन के अलावा किसी अन्य चीज़ के रूप में परिभाषित करने के लिए उपयोगी क्यों हो सकता है । उत्तर दोनों भागों के लिए एक स्पष्टीकरण प्रदान करता है।
dasblinkenlight

1
कि प्रतीक मेन नाम के अधीन नहीं है अप्रासंगिक है। C ++ मानक में नाम का उल्लेख नहीं है। नामकरण एक कार्यान्वयन मुद्दा है।
डेविड हैमेन

30

mainएक नहीं है आरक्षित शब्द यह सिर्फ एक है पूर्वनिर्धारित पहचानकर्ता (जैसे cin, endl, npos...) है, तो आप एक चर बुलाया घोषित कर सकता है main, यह प्रारंभ और उसके बाद अपने मूल्य प्रिंट आउट।

बेशक:

  • चेतावनी उपयोगी है क्योंकि यह काफी त्रुटि प्रवण है;
  • आपके पास main()फ़ंक्शन (लाइब्रेरी) के बिना एक स्रोत फ़ाइल हो सकती है ।

संपादित करें

कुछ संदर्भ:

  • main एक आरक्षित शब्द नहीं है (C ++ 11):

    फ़ंक्शन का mainउपयोग किसी प्रोग्राम के भीतर नहीं किया जाएगा। mainकार्यान्वयन (परिभाषित ) का लिंकेज (3.5) है। एक प्रोग्राम है जो मुख्य परिभाषित करता है के रूप में नष्ट या कि मुख्य वाणी होने के लिए inline, staticया constexprबीमार ही बना है। नाम mainअन्यथा आरक्षित नहीं है। [उदाहरण: सदस्य कार्यों, कक्षाओं और गणना को mainअन्य नामस्थानों में संस्थाओं के रूप में कहा जा सकता है। - अंतिम उदाहरण]

    C ++ 11 - [basic.start.main] 3.6.1.3

    [२.११ / ३] [...] कुछ पहचानकर्ता सी ++ कार्यान्वयन और मानक पुस्तकालयों (१ ).६.४.३.२) द्वारा उपयोग के लिए आरक्षित हैं और अन्यथा उपयोग नहीं किए जाएंगे; कोई निदान की आवश्यकता नहीं है।

    [१ [.६.४.३.२ / १] कुछ नाम और फ़ंक्शन हस्ताक्षर हमेशा कार्यान्वयन के लिए आरक्षित होते हैं:

    • प्रत्येक नाम जिसमें एक डबल अंडरस्कोर __ है या एक अंडरस्कोर के साथ शुरू होता है जिसके बाद एक अपरकेस अक्षर (2.12) किसी भी उपयोग के लिए कार्यान्वयन के लिए आरक्षित है।
    • अंडरस्कोर से शुरू होने वाला प्रत्येक नाम वैश्विक नामस्थान में एक नाम के रूप में उपयोग के लिए कार्यान्वयन के लिए आरक्षित है।
  • प्रोग्रामिंग भाषाओं में आरक्षित शब्द

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


- मुझे लगता है कि मैं नहीं बल्कि इस तथ्य से beguiled रहा है कि (के रूप में यह है तो प्रवण त्रुटि), क्यों यह एक चेतावनी (नहीं एक त्रुटि) है, और क्यों यह केवल एक चेतावनी के रूप में जब सी संकलित है - बेशक, आप बिना संकलन कर सकते हैं एक main()फ़ंक्शन, लेकिन आप इसे प्रोग्राम के रूप में लिंक नहीं कर सकते। यहाँ क्या हो रहा है कि एक "वैध" कार्यक्रम को बिना main(), सिर्फ एक से जोड़ा जा रहा है main
ज्योफ निक्सन

7
cinऔर endlडिफ़ॉल्ट नाम स्थान में नहीं हैं - वे stdनाम स्थान में हैं। nposका सदस्य है std::basic_string
20

1
main एक वैश्विक नाम के रूप में आरक्षित है। आपके द्वारा उल्लेखित अन्य चीजों में से कोई भी, न ही mainपूर्वनिर्धारित है।
पोटाटोस्वाटर

1
अनुमतियों के लिए C ++ 14 C3.6.1 और C11 .15.1.2.2.1 देखें जो होने mainकी अनुमति है। C ++ का कहना है कि "एक कार्यान्वयन मुख्य कार्य को पूर्वनिर्धारित नहीं करेगा" और C का कहना है कि "कार्यान्वयन इस फ़ंक्शन के लिए कोई प्रोटोटाइप घोषित नहीं करता है।"
पोटाटोसवेटर

@manlio: कृपया स्पष्ट करें कि आप क्या उद्धृत कर रहे हैं। सादे सी के रूप में हवाला देना गलत है। तो मुझे लगता है कि यह किसी भी है सी + + मानकों यह नहीं है?
ढिन

19

है int main;कोई मान्य C / C ++ प्रोग्राम?

यह पूरी तरह से स्पष्ट नहीं है कि C / C ++ प्रोग्राम क्या है।

है int main;कोई मान्य सी कार्यक्रम?

हाँ। एक फ्रीस्टैंडिंग कार्यान्वयन को इस तरह के कार्यक्रम को स्वीकार करने की अनुमति है। mainएक मुक्त वातावरण में कोई विशेष अर्थ नहीं है।

यह एक होस्ट किए गए वातावरण में मान्य नहीं है।

है int main;कोई मान्य सी ++ प्रोग्राम?

डिट्टो।

यह दुर्घटना क्यों करता है?

कार्यक्रम को आपके वातावरण में समझ में नहीं आता है। एक फ्रीस्टैंडिंग वातावरण में कार्यक्रम स्टार्टअप और समाप्ति, और का अर्थ main, कार्यान्वयन-परिभाषित हैं।

संकलक मुझे चेतावनी क्यों देता है?

कंपाइलर आपको चेतावनी दे सकता है कि वह जो भी चाहे, जब तक वह अनुरूप कार्यक्रमों को अस्वीकार नहीं करता है। दूसरी ओर, चेतावनी एक गैर-अनुरूपता कार्यक्रम का निदान करने के लिए आवश्यक है। चूँकि यह अनुवाद इकाई एक मान्य होस्ट प्रोग्राम का हिस्सा नहीं हो सकती है, एक नैदानिक ​​संदेश उचित है।

क्या gccएक स्वतंत्र वातावरण है, या यह एक होस्ट किया गया वातावरण है?

हाँ।

gcc-ffreestandingसंकलन ध्वज का दस्तावेज । इसे जोड़ें, और चेतावनी चली जाती है। आप चाहें तो इसका उपयोग कर सकते हैं जैसे कि गुठली या फर्मवेयर का निर्माण।

g++ऐसे झंडे का दस्तावेज नहीं देता है। लगता है कि इस कार्यक्रम पर इसका कोई प्रभाव नहीं है। यह मान लेना सुरक्षित है कि g ++ द्वारा प्रदान किया गया वातावरण होस्ट किया गया है। इस मामले में नैदानिक ​​की अनुपस्थिति एक बग है।


17

यह एक चेतावनी है क्योंकि यह तकनीकी रूप से अस्वीकृत नहीं है। स्टार्टअप कोड "मुख्य" के प्रतीक स्थान का उपयोग करेगा और तीन मानक तर्कों (argc, argv और envp) के साथ इसमें कूद जाएगा। यह नहीं है, और लिंक समय पर जाँच नहीं कर सकता है कि यह वास्तव में एक कार्य है, और न ही यह भी कि उनके पास यह तर्क हैं। यही कारण है कि int main (int argc, char ** argv) काम करता है - कंपाइलर को envp के तर्क के बारे में पता नहीं होता है और ऐसा होता है कि इसका उपयोग नहीं किया जाता है, और यह कॉलर-क्लीनअप है।

एक मजाक के रूप में, आप कुछ ऐसा कर सकते थे

int main = 0xCBCBCBCB;

एक x86 मशीन पर और, चेतावनियों और इसी तरह के सामान को नजरअंदाज करते हुए, यह न केवल संकलन करेगा बल्कि वास्तव में काम भी करेगा।

किसी ने इसके लिए एक तकनीक का उपयोग किया, जो एक निष्पादन योग्य (प्रकार) लिखने के लिए है जो सीधे कई आर्किटेक्चर पर चलता है - http://phrack.org/issues/57/17.html#article । इसका उपयोग IOCCC - http://www.ioccc.org/1984/mullender/mullender.c जीतने के लिए भी किया गया था ।


1
"यह एक चेतावनी है क्योंकि यह तकनीकी रूप से अस्वीकृत नहीं है" - यह C ++ में अमान्य है।
चीयर्स एंड हीथ। - अल्फा

3
"तीन मानक तर्क (argc, argv और envp)" - यहाँ आप संभवतः Posix मानक के बारे में बात कर रहे हैं।
चीयर्स एंड हीथ। - अल्फा

मेरे सिस्टम पर (Ubuntu 14 / x64), निम्नलिखित पंक्ति gcc के साथ काम करती है:int main __attribute__ ((section (".text")))= 0xC3C3C3C3;
csharpfolk

@ चेरसन्ध।-अल्फ पहले दो मानक हैं, तीसरा पोसिक्स है।
डैस्कैंडी

9

क्या यह एक वैध कार्यक्रम है?

नहीं।

यह एक कार्यक्रम नहीं है क्योंकि इसमें कोई निष्पादन योग्य भाग नहीं है।

क्या यह संकलन करने के लिए वैध है?

हाँ।

क्या इसे एक वैध कार्यक्रम के साथ इस्तेमाल किया जा सकता है?

हाँ।

सभी संकलित कोड को मान्य होने के लिए निष्पादन योग्य होने की आवश्यकता नहीं है। उदाहरण स्थिर और गतिशील पुस्तकालय हैं।

आपने प्रभावी रूप से एक ऑब्जेक्ट फ़ाइल बनाई है। यह एक मान्य निष्पादन योग्य नहीं है, हालांकि एक अन्य कार्यक्रम mainपरिणामी फ़ाइल में ऑब्जेक्ट को रनटाइम पर लोड करके लिंक कर सकता है।

क्या यह एक त्रुटि होनी चाहिए?

परंपरागत रूप से, C ++ उपयोगकर्ता को उन चीजों को करने की अनुमति देता है जो ऐसा लग सकता है कि उनका कोई वैध उपयोग नहीं है लेकिन यह भाषा के वाक्यविन्यास के साथ फिट है।

मेरा मतलब है कि यकीन है, यह एक त्रुटि के रूप में पुनर्वर्गीकृत किया जा सकता है, लेकिन क्यों? वह कौन सा उद्देश्य होगा जो चेतावनी नहीं देता है?

इसलिए जब तक इस कार्यक्षमता की एक वास्तविक संभावना वास्तविक कोड में उपयोग की जा रही है, तब तक यह संभव नहीं है कि गैर-फ़ंक्शन ऑब्जेक्ट के नाम mainपर भाषा के अनुसार त्रुटि हो।


यह बाहरी रूप से दिखाई देने वाला प्रतीक बनाता है जिसका नाम है main। कैसे एक वैध कार्यक्रम है, जो एक बाहर से दिखाई देने होना आवश्यक कर सकते हैं समारोह नामित main, यह के लिए लिंक?
कीथ थॉम्पसन

@KeithThompson रनटाइम पर लोड। स्पष्ट करेंगे।
माइकल गाज़ोन्डा

यह इसलिए है क्योंकि यह प्रतीक प्रकारों के बीच अंतर बताने में सक्षम नहीं है। लिंकिंग ठीक काम करता है - निष्पादन (सावधानी से तैयार किए गए मामले को छोड़कर) नहीं करता है।
क्रिस स्ट्रैटन

1
@ChrisStratton: मुझे लगता है कि कीथ का तर्क यह है कि लिंकिंग विफल हो जाती है क्योंकि प्रतीक को बहुतायत से परिभाषित किया जाता है ... क्योंकि "मान्य प्रोग्राम" तब तक एक वैध कार्यक्रम नहीं होगा जब तक कि यह एक mainफ़ंक्शन को परिभाषित नहीं करता है ।
बेन वोइगट

@BenVoigt लेकिन अगर यह किसी लाइब्रेरी में दिखाई देता है, तो लिंकिंग (और शायद नहीं) विफल हो सकती है, क्योंकि प्रोग्राम लिंक-टाइम पर, int main;परिभाषा दिखाई नहीं देगी।

6

मैं वास्तविक भाषा मानकों का हवाला देते हुए पहले से दिए गए उत्तरों को जोड़ना चाहूंगा।

'इंट मेन है?' एक वैध सी कार्यक्रम?

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

C11 से सभी निम्नलिखित उद्धरण

5. पर्यावरण

एक कार्यान्वयन सी स्रोत फ़ाइलों का अनुवाद करता है और सी प्रोग्राम को दो डेटाप्रोसेसिंग-सिस्टम वातावरण में निष्पादित करता है , जिसे अनुवाद पर्यावरण और निष्पादन वातावरण कहा जाएगा [...]

5.1.2 निष्पादन वातावरण

दो निष्पादन वातावरण परिभाषित किए गए हैं: फ्रीस्टैंडिंग और होस्ट। दोनों मामलों में, प्रोग्राम स्टार्टअप तब होता है जब एक निर्दिष्ट सी फ़ंक्शन निष्पादन पर्यावरण द्वारा कहा जाता है।

5.1.2.1 मुक्त वातावरण

एक फ्रीस्टैंडिंग वातावरण में (जिसमें सी प्रोग्राम का निष्पादन ऑपरेटिंग सिस्टम के किसी भी लाभ के बिना हो सकता है), प्रोग्राम स्टार्टअप पर नाम और प्रकार के फ़ंक्शन को कार्यान्वयन-परिभाषित किया जाता है।

5.1.2.2 होस्टेड वातावरण

एक होस्ट किया गया वातावरण प्रदान नहीं किया जाना चाहिए, लेकिन यदि मौजूद हो तो निम्नलिखित विनिर्देशों के अनुरूप होगा।

5.1.2.2.1 प्रोग्राम स्टार्टअप

प्रोग्राम स्टार्टअप पर कहा जाने वाला फ़ंक्शन मुख्य नाम दिया गया है । [...] इसे इंट के रिटर्न प्रकार के साथ और कोई मापदंडों के साथ परिभाषित किया जाएगा [...] या दो मापदंडों के साथ [...] या समकक्ष या किसी अन्य कार्यान्वयन-परिभाषित तरीके से।

इनमें से, निम्नलिखित मनाया जाता है:

  • C11 प्रोग्राम में एक फ्रीस्टैंडिंग या एक होस्ट किया गया निष्पादन वातावरण हो सकता है और मान्य हो सकता है।
  • यदि यह एक फ्रीस्टैंडिंग है, तो एक मुख्य कार्य मौजूद नहीं है।
  • अन्यथा, वहाँ एक वापसी के साथ होना चाहिए प्रकार int

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

'इंट मेन है?' एक वैध C ++ प्रोग्राम?

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

C ++ 14 से उद्धरण

3.6.1 मुख्य कार्य

एक कार्यक्रम में मुख्य नामक एक वैश्विक फ़ंक्शन शामिल होगा, जो कार्यक्रम की निर्दिष्ट शुरुआत है। यह कार्यान्वयन-परिभाषित है कि मुख्य कार्य को परिभाषित करने के लिए एक फ्रीस्टैंडिंग वातावरण में एक कार्यक्रम की आवश्यकता है या नहीं। [...] इसमें इंट का रिटर्न प्रकार होगा, लेकिन अन्यथा इसका प्रकार कार्यान्वयन-परिभाषित है। [...] मुख्य नाम अन्यथा आरक्षित नहीं है।

यहां, C11 मानक के विपरीत, फ्रीस्टैंडिंग निष्पादन पर्यावरण पर कम प्रतिबंध लागू होते हैं, क्योंकि किसी भी स्टार्टअप फ़ंक्शन का उल्लेख नहीं किया गया है, जबकि होस्ट किए गए निष्पादन वातावरण के लिए, मामला C11 के समान ही है।

दोबारा, मैं तर्क दूंगा कि होस्ट किए गए मामले के लिए, आपका कोड मान्य C ++ 14 प्रोग्राम नहीं है, लेकिन मुझे यकीन है कि यह फ्रीस्टैंडिंग केस के लिए है।

चूँकि मेरा जवाब केवल निष्पादन के माहौल पर विचार करता है, मुझे लगता है कि dasblinkenlicht द्वारा जवाब खेलने में आता है, जैसा कि अनुवाद के माहौल में होने वाला नामकरण पहले से होता है। यहाँ, मुझे इतना यकीन नहीं है कि उपरोक्त उद्धरण इतनी सख्ती से देखे गए हैं।


4

मेरी बात, मुझे लगता है, क्या मुझे लगता है कि यह एक मेजबान वातावरण में एक त्रुटि होनी चाहिए, एह?

त्रुटि आपकी है। आपने एक फ़ंक्शन का नाम निर्दिष्ट नहीं किया है mainजो एक रिटर्न देता है intऔर एक होस्ट किए गए वातावरण में अपने प्रोग्राम का उपयोग करने का प्रयास किया है।

मान लीजिए कि आपके पास एक संकलन इकाई है जो नाम के एक वैश्विक चर को परिभाषित करती है main। यह एक स्वतंत्र वातावरण में अच्छी तरह से कानूनी हो सकता है क्योंकि फ्रीस्टैंडिंग वातावरण में कार्यान्वयन के लिए एक कार्यक्रम का गठन किया जाता है।

मान लीजिए कि आपके पास एक और संकलन इकाई है जो एक वैश्विक फ़ंक्शन को परिभाषित करती है जिसका नाम mainहै रिटर्न ए intऔर कोई तर्क नहीं लेता है। यह वही है जो एक होस्ट किए गए वातावरण में एक कार्यक्रम की आवश्यकता है।

सब कुछ ठीक है अगर आप केवल एक फ्रीस्टैंडिंग वातावरण में पहली संकलन इकाई का उपयोग करते हैं और केवल एक होस्ट किए गए वातावरण में दूसरे का उपयोग करते हैं। यदि आप एक कार्यक्रम में दोनों का उपयोग करते हैं तो क्या होगा? C ++ में, आपने एक परिभाषा नियम का उल्लंघन किया है। यह अपरिभाषित व्यवहार है। सी में, आपने उस नियम का उल्लंघन किया है जो तय करता है कि एक ही प्रतीक के सभी संदर्भ सुसंगत होने चाहिए; यदि वे अपरिभाषित व्यवहार नहीं कर रहे हैं। अपरिभाषित व्यवहार "जेल से बाहर, मुक्त!" एक कार्यान्वयन के डेवलपर्स को कार्ड। अपरिभाषित व्यवहार के जवाब में एक कार्यान्वयन कुछ भी करता है मानक के अनुरूप है। कार्यान्वयन के बारे में चेतावनी नहीं है, अकेले पता लगाने के लिए, अपरिभाषित व्यवहार करते हैं।

क्या होगा यदि आप उन संकलन इकाइयों में से केवल एक का उपयोग करते हैं, लेकिन आप गलत एक का उपयोग करते हैं (जो आपने किया था)? सी में, स्थिति स्पष्ट-कट है। mainएक होस्ट किए गए वातावरण में दो मानक रूपों में से एक में फ़ंक्शन को परिभाषित करने में विफलता अपरिभाषित व्यवहार है। मान लीजिए कि आपने बिल्कुल भी परिभाषित नहीं किया है main। कंपाइलर / लिंकर इस त्रुटि के बारे में एक बात कहना नहीं चाहता है। वे शिकायत करते हैं कि उनकी ओर से एक अच्छाई है। यह कि C प्रोग्राम बिना किसी त्रुटि के संकलित और जुड़ा हुआ है, आपकी गलती है, न कि संकलक की।

यह C ++ में थोड़ा कम स्पष्ट है क्योंकि mainएक होस्ट किए गए वातावरण में फ़ंक्शन को परिभाषित करने में विफलता अपरिभाषित व्यवहार के बजाय एक त्रुटि है (दूसरे शब्दों में, इसका निदान किया जाना चाहिए)। हालाँकि, C ++ में वन डेफिनिशन रूल का मतलब लिंकर्स डंबल हो सकता है। लिंकर की नौकरी बाहरी संदर्भों को हल कर रही है, और एक परिभाषा नियम के लिए धन्यवाद, लिंक करने वाले को यह जानने की जरूरत नहीं है कि उन प्रतीकों का क्या मतलब है। आपने नाम का एक प्रतीक प्रदान किया है main, लिंकर नाम के प्रतीक को देखने की उम्मीद कर रहा है main, इसलिए जहां तक ​​लिंकर का संबंध है, सभी अच्छे हैं।


4

C के लिए अब तक यह कार्यान्वित परिभाषित व्यवहार है।

जैसा कि ISO / IEC9899 कहता है:

5.1.2.2.1 प्रोग्राम स्टार्टअप

1 प्रोग्राम स्टार्टअप पर कहे जाने वाले फ़ंक्शन को मुख्य नाम दिया गया है। कार्यान्वयन इस फ़ंक्शन के लिए कोई प्रोटोटाइप घोषित नहीं करता है। इसे इंट के रिटर्न प्रकार और बिना किसी पैरामीटर के साथ परिभाषित किया जाएगा:

int main(void) { /* ... */ }

या दो मापदंडों के साथ (जिसे यहाँ argc और argv के रूप में संदर्भित किया जाता है, हालांकि किसी भी नाम का उपयोग किया जा सकता है, क्योंकि वे उस फ़ंक्शन के लिए स्थानीय हैं जिसमें उन्हें घोषित किया गया है):

int main(int argc, char *argv[]) { /* ... */ }

या उसके बराबर; या कुछ अन्य कार्यान्वयन-परिभाषित तरीके से।


3

नहीं, यह एक वैध कार्यक्रम नहीं है।

C ++ के लिए यह हाल ही में दोषपूर्ण रिपोर्ट 1886 द्वारा स्पष्ट रूप से बीमार बनाया गया था: मुख्य के लिए भाषा लिंकेज () जो कहता है:

एक स्पष्ट भाषा लिंकेज देने के लिए कोई प्रतिबंध नहीं लगता है, लेकिन यह संभवतः बीमार या सशर्त रूप से समर्थित होना चाहिए।

और रिज़ॉल्यूशन के भाग में निम्नलिखित परिवर्तन शामिल थे:

एक प्रोग्राम जो वैश्विक दायरे में एक चर मुख्य घोषित करता है या जो सी भाषा लिंकेज (किसी भी नामस्थान में) के साथ मुख्य नाम घोषित करता है, बीमार है।

हम इस सीडिंग को नवीनतम C ++ ड्राफ्ट मानक N4527 में पा सकते हैं जो C ++ 1z ड्राफ्ट है।

क्लैंग और जीसीसी दोनों के नवीनतम संस्करण अब इसे एक त्रुटि बनाते हैं ( इसे लाइव देखें ):

error: main cannot be declared as global variable
int main;
^

इस दोष रिपोर्ट से पहले, यह अपरिभाषित व्यवहार था जिसे निदान की आवश्यकता नहीं होती है। दूसरी ओर बीमार-गठित कोड को निदान की आवश्यकता होती है, संकलक या तो इसे चेतावनी या त्रुटि बना सकता है।


अद्यतन के लिए धन्यवाद! यह देखने के लिए महान अब संकलक निदान के साथ उठाया जा रहा है। हालाँकि, मुझे कहना होगा कि मुझे C ++ मानक गड़बड़ी में बदलाव देखने को मिलते हैं। (पृष्ठभूमि के लिए, के नाम mangling के बारे में ऊपर टिप्पणियों को देखने main()।) मैं अनुमति न देने के लिए तर्क को समझने के main()लिए कोई स्पष्ट संबंध-विनिर्देश होने से है, लेकिन मैं नहीं है यह समझना अनिवार्य है कि main()है सी ++ लिंकेज । बेशक मानक सीधे कैसे ABI लिंकेज / नाम mangling को संभालने के लिए पता, लेकिन व्यवहार में (जैसे कि, इटेनियम एबीआई) के साथ इस वध करना होगा नहीं है main()करने के लिए _Z4mainv। मैं क्या खो रहा हूँ?
ज्योफ निक्सन

मुझे लगता है कि सुपरकैट की टिप्पणी इसमें शामिल है। यदि उपयोगकर्ता द्वारा परिभाषित मुख्य को कॉल करने से पहले कार्यान्वयन अपनी बात कर रहा है, तो वह आसानी से एक बदले हुए नाम को कॉल करना चुन सकता है।
शफीक यघमौर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.