2008-12-21 21 views
8

यह एक बुनियादी सवाल है, लेकिन एक महत्वपूर्ण कोई भी कम ...क्या तर्क [0] निष्पादन का मार्ग होने की गारंटी है?

जब एक सी ++ प्रोग्राम जिसका मुख्य विधि निम्नलिखित आम हस्ताक्षर हैं शुरू करने:

int main(int argc, char* args[]) { 
    //Magic! 
    return 0; 
} 

आर्ग है [0 ] हमेशा वर्तमान में चल रहे कार्यक्रम के लिए मार्ग होने की गारंटी है? क्रॉस प्लेटफार्म के बारे में क्या (क्योंकि मैं एक लिनक्स पर्यावरण में हूं लेकिन बाद में पोर्ट बंद कर सकता हूं।)?

उत्तर

21

यह हमेशा नहीं होता है। यह वह मूल्य है जिसे आपने ऑपरेशन सिस्टम द्वारा प्रोग्राम दिया था। उदाहरण के लिए एक कार्यक्रम exec का उपयोग कर आप एक मनमाना मूल्य के लिए सेट कर सकते हैं कि प्रारंभ करने वाले:

int execve(const char *filename, char *const argv[], 
      char *const envp[]); 

पहले पैरामीटर फाइल शुरू करने के लिए है, और argv इच्छा मुख्य लिए argv [0] और अन्य सभी पैरामीटर हैं। envp में पर्यावरण चर शामिल हैं (मानक सी या सी ++ द्वारा परिभाषित नहीं है। यह एक पॉज़िक्स चीज़ है)।

कार्यान्वयन मुख्य कार्य पूर्वनिर्धारित नहीं होगी:

दरअसल, इस C++ argv की परिभाषा है। यह फ़ंक्शन ओवरलोड नहीं किया जाएगा। यह में रिटर्न प्रकार प्रकार int है, लेकिन अन्यथा इसका प्रकार कार्यान्वयन-परिभाषित है। सभी कार्यान्वयन मुख्य की निम्नलिखित परिभाषा के दोनों के लिए अनुमति देने होंगे:

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

और

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

बाद वाले मिलकर argc में करने के लिए पारित कर दिया तर्क की संख्या होगी में पर्यावरण से प्रोग्राम जो प्रोग्राम चलाया जाता है। अगर argc nonzero है, तो इन तर्कों को argv[0] argv[argc-1] में प्रदान किया जाएगा, जो शून्य-समाप्त मल्टीबाइट स्ट्रिंग्स (NTMBSs) (17.3.2.1.3.2) और argv[0] के प्रारंभिक वर्णों के पॉइंटर्स के रूप में एनटीएमबीएस के प्रारंभिक चरित्र के सूचक होंगे जो प्रोग्राम को आमंत्रित करने के लिए इस्तेमाल किए गए नाम का प्रतिनिधित्व करता है। Argc का मान nonnegative होगा। argv[argc] का मान 0 होगा। [नोट: यह अनुशंसा की जाती है कि argv के बाद कोई और (वैकल्पिक) पैरामीटर जोड़ा जाए। ]

यह कार्यान्वयन के लिए बहुत अधिक है जो "प्रोग्राम को आमंत्रित करने के लिए उपयोग किए जाने वाले नाम" को परिभाषित करता है। यदि आप अपने निष्पादन योग्य का पूरा पथ प्राप्त करना चाहते हैं, तो आप GetModuleFileName विंडोज पर और argv[0] (निष्पादित करने के लिए उपयोग किए जाने वाले नाम को प्राप्त करने के लिए, रिश्तेदार हो सकते हैं) getcwd (मौजूदा कार्य निर्देशिका प्राप्त करने के लिए, नाम बनाने की कोशिश कर रहे हैं) पूर्ण)।

+0

उदाहरण के लिए, एक खोल जानता है कि यह एक लॉगिन खोल है क्योंकि लॉगिन (1) एक डैश से शुरू करने के लिए argv [0] की व्यवस्था करता है। –

+0

... और बैश जानता है कि यह argv [0] से "sh" की तुलना करके POSIX मोड में है :) आकस्मिक रूप से, यह argv चालबाजी व्यस्त बॉक्स को इतना छोटा बनाता है। सभी utils एक बाइनरी में एक साथ पैक कर रहे हैं जो सिर्फ विभिन्न argv [0] मान –

+0

के साथ निष्पादित किया गया है मैं पोर्टेबल कार्यक्रमों में realpath से बचें। POSIX रीयलपाथ इंटरफ़ेस टूटा हुआ है, क्योंकि आप लक्ष्य बफर के आकार को निर्दिष्ट नहीं कर सकते हैं, न ही PATH_MAX के बारे में धारणा किए बिना पर्याप्त एक बड़ा आवंटित कर सकते हैं। – Doug

2

यहाँ सी मानक का कहना है कि argv[0] होना चाहिए:

तो argc का मूल्य से अधिक शून्य, स्ट्रिंग argv[0] प्रोग्राम नाम का प्रतिनिधित्व करता है के द्वारा की ओर इशारा किया है, argv[0][0] शून्य वर्ण होगा यदि प्रोग्राम का नाम होस्ट वातावरण से उपलब्ध नहीं है।

चाहे इसमें पूर्ण पथ शामिल है, जवाब यह है कि argv [0] में निष्पादन योग्य के लिए पूर्ण पथ आवश्यक नहीं है। विंडोज़ पर यह वही है जो कमांड लाइन पर प्रदान किया गया था। डुनो क्या लिनक्स/यूनिक्स करता है।

5

नहीं विंडोज पर GetModuleFileName वर्तमान निष्पादन कार्यक्रम के लिए सटीक पूर्ण पथ प्रदान करता है। लिनक्स पर एक सिम्लिंक/proc/self/exe है। वर्तमान में निष्पादन कार्यक्रम का पूरा पथ प्राप्त करने के लिए इस सिम्लिंक पर एक रीडलिंक करें। यहां तक ​​कि अगर आपको प्रोग्राम को थोरुग कहा जाता है तो एक सिम्लिंक/proc/self/exe हमेशा actuall प्रोग्राम को इंगित करेगा।

3

यह इतना गारंटी नहीं है कि छात्र इस तथ्य को छिपाने की कोशिश करते थे कि वे सी प्रोग्राम लिखकर स्कूल मेनफ्रेम पर दुष्ट खेल रहे थे जो इसे "सीसी" या "टीसीएच" के argv [0] के साथ शुरू करेंगे।

+1

'ps' और 'w' के पुराने पर्याप्त संस्करणों के साथ यह भी काम करता है। :) – chaos

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