खोज…


परिचय

सी भाषा पारंपरिक रूप से एक संकलित भाषा है (व्याख्या के विपरीत)। सी स्टैंडर्ड अनुवाद चरणों को परिभाषित करता है , और उन्हें लागू करने का उत्पाद एक प्रोग्राम इमेज (या संकलित प्रोग्राम) है। में , चरणों §5.1.1.2 में सूचीबद्ध हैं।

टिप्पणियों

फ़ाइल नाम विस्तार विवरण
.c मूल फाइल। आमतौर पर परिभाषाएँ और कोड होते हैं।
.h शीर्ष लेख फ़ाइल। आमतौर पर घोषणाएं होती हैं।
.o ऑब्जेक्ट फ़ाइल। मशीन भाषा में संकलित कोड।
.obj ऑब्जेक्ट फ़ाइलों के लिए वैकल्पिक विस्तार।
.a लाइब्रेरी फ़ाइल। ऑब्जेक्ट फ़ाइलों का पैकेज।
.dll विंडोज पर डायनेमिक-लिंक लाइब्रेरी।
.so कई यूनिक्स जैसी प्रणालियों पर साझा वस्तु (पुस्तकालय)।
.dylib OSX पर डायनेमिक-लिंक लाइब्रेरी (यूनिक्स संस्करण)।
.exe , .com विंडोज निष्पादन योग्य फ़ाइल। ऑब्जेक्ट फ़ाइलों और लाइब्रेरी फ़ाइलों को लिंक करके बनाया गया है। यूनिक्स जैसी प्रणालियों में, निष्पादन योग्य फ़ाइल के लिए कोई विशेष फ़ाइल नाम एक्सटेंशन नहीं है।
POSIX c99 संकलक झंडे विवरण
-o filename आउटपुट फ़ाइल नाम उदा। ( bin/program.exe , program )
-I directory direrctory में हेडर की खोज।
-D name स्थूल name परिभाषित name
-L directory directory में पुस्तकालयों के लिए खोज।
-l name लिंक पुस्तकालय libname

POSIX प्लेटफार्मों (लिनक्स, मेनफ्रेम, मैक) पर कंपाइलर आमतौर पर इन विकल्पों को स्वीकार करते हैं, भले ही उन्हें c99 नहीं कहा जाता c99

जीसीसी (जीएनयू कंपाइलर कलेक्शन) झंडे विवरण
-Wall उन सभी चेतावनी संदेशों को सक्षम करता है जिन्हें आमतौर पर उपयोगी माना जाता है।
-Wextra अधिक चेतावनी संदेश सक्षम करता है, बहुत शोर हो सकता है।
-pedantic बल चेतावनियाँ जहाँ कोड चुने गए मानक का उल्लंघन करता है।
-Wconversion अंतर्निहित रूपांतरण पर चेतावनी सक्षम करें, देखभाल के साथ उपयोग करें।
-c लिंक के बिना स्रोत फ़ाइलों को संकलित करता है।
-v प्रिंट संकलन जानकारी।
  • gcc POSIX झंडे को स्वीकार करता है और बहुत से अन्य।
  • POSIX प्लेटफ़ॉर्म पर कई अन्य कंपाइलर ( clang , वेंडर विशिष्ट कंपाइलर) भी ऊपर सूचीबद्ध झंडे का उपयोग करते हैं।
  • और भी कई विकल्पों के लिए GCC को शामिल करते हुए देखें।
टीसीसी (टिनी सी कंपाइलर) झंडे विवरण
-Wimplicit-function-declaration अंतर्निहित फ़ंक्शन घोषणा के बारे में चेतावनी दें।
-Wunsupported असमर्थित GCC सुविधाओं के बारे में चेतावनी जो TCC द्वारा अनदेखा की जाती है।
-Wwrite-strings स्ट्रिंग स्थिरांक को * * के बजाय टाइप कास्ट चार का बनाएं।
-Werror चेतावनी जारी होने पर संकलन रद्द करें।
-Wall सभी चेतावनियों को सक्रिय करें, सिवाए -Werror , -Wunusupported और -Wwrite strings

द लिंकर

लिंकर का काम बाइनरी एक्ज़ीक्यूटेबल में ऑब्जेक्ट फ़ाइलों ( .o फ़ाइलों) के एक गुच्छा को एक साथ जोड़ना है। मुख्य रूप से जोड़ने की प्रक्रिया में सांकेतिक पतों को सांकेतिक पतों को हल करना शामिल है। लिंक प्रक्रिया का परिणाम आम तौर पर एक निष्पादन योग्य कार्यक्रम है।

लिंक प्रक्रिया के दौरान, लिंकर कमांड लाइन पर निर्दिष्ट सभी ऑब्जेक्ट मॉड्यूल को उठाएगा, सामने कुछ सिस्टम-विशिष्ट स्टार्टअप कोड जोड़ देगा और ऑब्जेक्ट ऑब्जेक्ट में सभी बाहरी संदर्भों को अन्य ऑब्जेक्ट फ़ाइलों (ऑब्जेक्ट फ़ाइलों) में बाहरी परिभाषाओं के साथ हल करने का प्रयास करेगा सीधे कमांड लाइन पर निर्दिष्ट किया जा सकता है या पुस्तकालयों के माध्यम से जोड़ा जा सकता है)। यह तब ऑब्जेक्ट फ़ाइलों के लिए लोड पते निर्दिष्ट करेगा, अर्थात, यह निर्दिष्ट करता है कि कोड और डेटा समाप्त कार्यक्रम के पता स्थान में कहां समाप्त होगा। एक बार जब इसे लोड पते मिल जाते हैं, तो यह ऑब्जेक्ट के कोड में सभी प्रतीकात्मक पते को "वास्तविक", लक्ष्य के पते के स्थान में संख्यात्मक पते से बदल सकता है। कार्यक्रम अब निष्पादित करने के लिए तैयार है।

इसमें दोनों ऑब्जेक्ट फ़ाइलें शामिल हैं जो आपके स्रोत कोड फ़ाइलों के साथ-साथ आपके लिए पूर्व-संकलित की गई लाइब्रेरी फ़ाइलों में संग्रहित की गई फ़ाइलों के साथ-साथ संकलित की गई हैं। इन फ़ाइलों के नाम हैं जो .a या .so में समाप्त होते हैं, और आपको सामान्यतः उनके बारे में जानने की आवश्यकता नहीं होती है, क्योंकि लिंकर को पता होता है कि उनमें से अधिकांश कहाँ स्थित हैं और आवश्यकतानुसार उन्हें स्वचालित रूप से लिंक करेंगे।

लिंकर का इंप्लिमेंट इनवोकेशन

प्री-प्रोसेसर की तरह, लिंकर एक अलग प्रोग्राम है, जिसे अक्सर ld (लेकिन लिनक्स collect2 का उपयोग करता है, उदाहरण के लिए) कहा जाता है। प्री-प्रोसेसर की तरह ही, कंपाइलर का उपयोग करने पर लिंकर आपके लिए अपने आप आ जाता है। इस प्रकार, लिंकर का उपयोग करने का सामान्य तरीका इस प्रकार है:

% gcc foo.o bar.o baz.o -o myprog

यह रेखा कंपाइलर को तीन ऑब्जेक्ट फाइल्स ( foo.o , bar.o , और baz.o ) को एक द्विआधारी निष्पादन योग्य फ़ाइल में myprog नाम से myprog । अब आपके पास myprog नाम की एक फाइल है जिसे आप चला सकते हैं और जो उम्मीद है कि कुछ अच्छा और / या उपयोगी होगा।

लिंकर का स्पष्ट आह्वान

सीधे लिंकर को लागू करना संभव है, लेकिन यह शायद ही कभी उचित है, और आमतौर पर बहुत ही प्लेटफॉर्म-विशिष्ट है। यही है, लिनक्स पर काम करने वाले विकल्प सोलारिस, एआईएक्स, मैकओएस, विंडोज और इसी तरह किसी अन्य प्लेटफॉर्म के लिए आवश्यक रूप से काम नहीं करेंगे। यदि आप GCC के साथ काम करते हैं, तो आप अपनी ओर से निष्पादित किए गए कार्यों को देखने के लिए gcc -v का उपयोग कर सकते हैं।

लिंकर के लिए विकल्प

लिंकर इसे व्यवहार को संशोधित करने के लिए कुछ तर्क भी देता है। निम्न आदेश gcc को foo.o और bar.o को जोड़ने के लिए bar.o , लेकिन इसमें ncurses लाइब्रेरी भी शामिल होगी।

% gcc foo.o bar.o -o foo -lncurses

यह वास्तव में (अधिक या कम) के बराबर है

% gcc foo.o bar.o /usr/lib/libncurses.so -o foo

(हालांकि libncurses.so हो सकता है libncurses.a , जो अभी-अभी संग्रह के साथ बनाया है ar )। ध्यान दें कि आपको ऑब्जेक्ट फ़ाइलों के बाद पुस्तकालयों (या तो पथनाम या -lname विकल्पों के माध्यम से) को सूचीबद्ध करना चाहिए। स्थैतिक पुस्तकालयों के साथ, आदेश कि वे निर्दिष्ट मामले हैं; अक्सर साझा पुस्तकालयों के साथ, आदेश कोई फर्क नहीं पड़ता।

ध्यान दें कि कई प्रणालियों पर, यदि आप गणितीय कार्यों ( <math.h> ) का उपयोग कर रहे हैं, तो आपको गणित पुस्तकालय को लोड करने के लिए -lm निर्दिष्ट करने की आवश्यकता है - लेकिन मैक ओएस एक्स और मैकओएस सिएरा को इसकी आवश्यकता नहीं है। अन्य पुस्तकालय हैं जो लिनक्स और अन्य यूनिक्स प्रणालियों पर अलग-अलग पुस्तकालय हैं, लेकिन मैकओएस पर नहीं - पॉसिक्स थ्रेड्स, और पॉसिक्स रियलटाइम, और नेटवर्किंग लाइब्रेरी उदाहरण हैं। नतीजतन, लिंकिंग प्रक्रिया प्लेटफार्मों के बीच भिन्न होती है।

अन्य संकलन विकल्प

यह आपको अपने स्वयं के सी कार्यक्रमों को संकलित करने के लिए जानने की आवश्यकता है। आमतौर पर, हम यह भी सलाह देते हैं कि आप -Wall कमांड लाइन विकल्प का उपयोग करें:

% gcc -Wall -c foo.cc

-Wall ऑप्शन के कारण कंपाइलर आपको कानूनी लेकिन संदिग्ध कोड के निर्माण के बारे में चेतावनी देता है, और आपको बहुत जल्दी कीड़े पकड़ने में मदद करेगा।

यदि आप चाहते हैं कि कंपाइलर आप पर अधिक चेतावनियाँ फेंकें (घोषित किए गए चरों सहित, लेकिन उपयोग नहीं किए जाते हैं, तो मूल्य वापस करना आदि), आप विकल्प के इस सेट का उपयोग कर सकते हैं, जैसे -Wall , नाम के बावजूद, बारी नहीं है। सभी संभावित चेतावनियों पर:

% gcc -Wall -Wextra -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wlogical-op \
>     -Wmissing-declarations -Wredundant-decls -Wshadow …

ध्यान दें कि clang का विकल्प है -Weverything जो वास्तव में सभी चेतावनियों को चालू करता clang

फ़ाइल प्रकारों

C कार्यक्रमों को संकलित करने के लिए आपको पाँच प्रकार की फ़ाइलों के साथ काम करना पड़ता है:

  1. स्रोत फ़ाइलें : इन फ़ाइलों में फ़ंक्शन परिभाषाएँ होती हैं, और ऐसे नाम होते हैं जो कन्वेंशन द्वारा .c में समाप्त होते हैं। नोट: .cc .cpp C ++ फाइलें हैं; सी फाइलें नहीं
    जैसे, foo.c

  2. हैडर फाइलें : इन फाइलों में फ़ंक्शन प्रोटोटाइप और विभिन्न प्री-प्रोसेसर स्टेटमेंट (नीचे देखें) हैं। वे स्रोत कोड फ़ाइलों को बाहरी रूप से परिभाषित कार्यों तक पहुंचने की अनुमति देने के लिए उपयोग किए जाते हैं। सम्मलेन द्वारा हेडर फाइलें .h में समाप्त होती हैं।
    जैसे, foo.h

  3. ऑब्जेक्ट फ़ाइलें : इन फ़ाइलों को कंपाइलर के आउटपुट के रूप में उत्पादित किया जाता है। वे बाइनरी रूप में फ़ंक्शन परिभाषाओं से मिलकर होते हैं, लेकिन वे स्वयं द्वारा निष्पादित नहीं होते हैं। वस्तु फ़ाइलों में खत्म हो .o , प्रथा के अनुसार, हालांकि कुछ ऑपरेटिंग सिस्टम पर (जैसे विंडोज, MS-DOS), वे अक्सर में खत्म हो .obj
    जैसे, foo.o foo.obj

  4. बाइनरी निष्पादनयोग्य : ये एक प्रोग्राम के आउटपुट के रूप में उत्पन्न होते हैं, जिन्हें "लिंकर" कहा जाता है। लिंकर एक बाइनरी फ़ाइल का उत्पादन करने के लिए कई ऑब्जेक्ट फ़ाइलों को एक साथ जोड़ता है जिसे सीधे निष्पादित किया जा सकता है। यूनिक्स ऑपरेटिंग सिस्टम पर बाइनरी एक्ज़िबिट का कोई विशेष प्रत्यय नहीं है, हालाँकि वे आम तौर पर विंडोज में .exe में समाप्त होते हैं।
    जैसे, foo foo.exe

  5. पुस्तकालय : एक पुस्तकालय एक संकलित बाइनरी है, लेकिन अपने आप में एक निष्पादन योग्य नहीं है (यानी, पुस्तकालय में कोई main() फ़ंक्शन नहीं है)। एक पुस्तकालय में ऐसे कार्य होते हैं जिनका उपयोग एक से अधिक कार्यक्रमों द्वारा किया जा सकता है। एक पुस्तकालय को हेडर फ़ाइलों के साथ जहाज करना चाहिए जिसमें पुस्तकालय में सभी कार्यों के लिए प्रोटोटाइप होते हैं; इन हेडर फ़ाइलों को संदर्भित किया जाना चाहिए (जैसे; #include <library.h> ) किसी भी स्रोत फ़ाइल में जो लाइब्रेरी का उपयोग करता है। लिंकर को फिर पुस्तकालय में भेजा जाना चाहिए ताकि कार्यक्रम सफलतापूर्वक संकलित किया जा सके। पुस्तकालय दो प्रकार के होते हैं: स्थिर और गतिशील।

    • स्टेटिक लाइब्रेरी : एक स्टैटिक लाइब्रेरी (। POSIX सिस्टम के लिए .a फाइल और विंडोज के लिए .lib फाइलें - DLL इंपोर्ट लाइब्रेरी फाइल के साथ भ्रमित नहीं होना चाहिए, जो .lib एक्सटेंशन का भी उपयोग करते हैं) स्टेटिक रूप से प्रोग्राम में बनाया गया है। स्टेटिक लाइब्रेरीज़ का यह लाभ है कि प्रोग्राम को यह पता चल जाता है कि लाइब्रेरी के कौन से संस्करण का उपयोग किया जाता है। दूसरी ओर, निष्पादन योग्य का आकार बड़ा है क्योंकि सभी उपयोग किए गए पुस्तकालय कार्यों में शामिल हैं।
      जैसे, libfoo.a foo.lib
    • गतिशील पुस्तकालय: एक गतिशील पुस्तकालय ( .so सबसे POSIX सिस्टम के लिए फ़ाइलें, .dylib के लिए OSX और .dll विंडोज के लिए फ़ाइलें) गतिशील रूप से इस कार्यक्रम के द्वारा रनटाइम पर जुड़ा हुआ है। इन्हें कभी-कभी साझा पुस्तकालयों के रूप में भी जाना जाता है क्योंकि एक पुस्तकालय छवि को कई कार्यक्रमों द्वारा साझा किया जा सकता है। यदि एक से अधिक एप्लिकेशन लाइब्रेरी का उपयोग कर रहे हैं तो डायनामिक लाइब्रेरी में डिस्क स्थान कम होने का फायदा है। इसके अलावा, वे निष्पादन योग्यताओं के पुनर्निर्माण के बिना पुस्तकालय अपडेट (बग फिक्स) की अनुमति देते हैं।
      जैसे, foo.so foo.dylib foo.dll

प्रीप्रोसेसर

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

प्रीप्रोसेसर कमांड्स पाउंड साइन ("#") से शुरू होती हैं। कई प्रीप्रोसेसर कमांड हैं; दो सबसे महत्वपूर्ण हैं:

  1. परिभाषित करता है :

    #define का उपयोग मुख्य रूप से स्थिरांक को परिभाषित करने के लिए किया जाता है। उदाहरण के लिए,

    #define BIGNUM 1000000
    int a = BIGNUM; 
    

    हो जाता है

    int a = 1000000;
    

    #define का उपयोग इस तरह से किया जाता है ताकि स्रोत कोड फ़ाइल में कई अलग-अलग स्थानों में स्पष्ट रूप से कुछ स्थिर मूल्य लिखने से बचें। यदि आपको बाद में निरंतर मूल्य बदलने की आवश्यकता है तो यह महत्वपूर्ण है; यह #define में एक बार बदलने के लिए बहुत कम बग-प्रवण है, इसे कोड में बिखरे हुए कई स्थानों पर बदलना पड़ता है।

    क्योंकि #define सिर्फ उन्नत खोज और प्रतिस्थापित करता है, आप मैक्रोज़ की घोषणा भी कर सकते हैं। उदाहरण के लिए:

    #define ISTRUE(stm) do{stm = stm ? 1 : 0;}while(0)
    // in the function:
    a = x;
    ISTRUE(a);
    

    हो जाता है:

    // in the function:
    a = x;
    do {
        a = a ? 1 : 0;
    } while(0);
    

    पहले सन्निकटन में, यह प्रभाव लगभग इनलाइन फ़ंक्शंस के समान है, लेकिन प्रीप्रोसेसर #define मैक्रोज़ के लिए प्रकार की जाँच प्रदान नहीं करता है। यह अच्छी तरह से त्रुटि-ग्रस्त होने के लिए जाना जाता है और उनके उपयोग के लिए बहुत सावधानी की आवश्यकता होती है।

    यहां यह भी ध्यान दें, कि प्रीप्रोसेसर भी एक रिक्त स्थान के साथ टिप्पणियों को बदल देगा जैसा कि नीचे बताया गया है।

  2. शामिल हैं :

    #include स्रोत कोड फ़ाइल के बाहर परिभाषित फ़ंक्शन परिभाषाओं तक पहुंचने के लिए उपयोग किया जाता है। उदाहरण के लिए:

     #include <stdio.h> 
    

    प्रीप्रोसेसर के कारण संकलित होने से पहले #include स्टेटमेंट के स्थान पर <stdio.h> की सामग्री को सोर्स कोड फ़ाइल में पेस्ट करना है। #include का उपयोग लगभग हमेशा हेडर फ़ाइलों को शामिल करने के लिए किया जाता है, जो कि ऐसी फाइलें हैं जिनमें मुख्य रूप से फ़ंक्शन घोषणाएं और #define स्टेटमेंट होते हैं। इस स्थिति में, हम printf और scanf जैसे कार्यों का उपयोग करने में सक्षम होने के लिए #include का उपयोग करते हैं, जिनकी घोषणाएं फ़ाइल stdio.h में स्थित हैं। सी कंपाइलर आपको किसी फ़ंक्शन का उपयोग करने की अनुमति नहीं देते हैं जब तक कि यह पहले से उस फ़ाइल में घोषित या परिभाषित नहीं किया गया हो; इस तरह #include स्टेटमेंट आपके C प्रोग्राम्स में पहले से लिखे हुए कोड को फिर से इस्तेमाल करने का तरीका है।

  3. तर्क संचालन :

    #if defined A || defined B
    variable = another_variable + 1;
    #else
    variable = another_variable * 2;
    #endif
    

    इसे बदल दिया जाएगा:

    variable = another_variable + 1;
    

    यदि A या B पहले प्रोजेक्ट में कहीं परिभाषित किए गए थे। यदि यह मामला नहीं है, तो निश्चित रूप से प्रीप्रोसेसर ऐसा करेगा:

    variable = another_variable * 2;
    

    यह अक्सर कोड के लिए उपयोग किया जाता है, जो विभिन्न प्रणालियों पर चलता है या विभिन्न संकलक पर संकलित होता है। चूँकि ग्लोबल डिफाइन हैं, जो कंपाइलर / सिस्टम स्पेसिफिक हैं, आप उन डिफाइन पर टेस्ट कर सकते हैं और हमेशा कंपाइलर को उस कोड का उपयोग करने दें, जिसे वह सुनिश्चित करेगा।

  4. टिप्पणियाँ

    प्रीप्रोसेसर स्रोत फ़ाइल में सभी टिप्पणियों को एक स्थान से बदलता है। टिप्पणियाँ // रेखा के अंत तक, या खोलने /* और समापन */ टिप्पणी कोष्ठक के संयोजन द्वारा इंगित की जाती हैं।

संकलक

सी के बाद प्री-प्रोसेसर ने सभी हेडर फ़ाइलों को शामिल किया है और सभी मैक्रोज़ का विस्तार किया है, कंपाइलर प्रोग्राम को संकलित कर सकता है। यह C स्रोत कोड को ऑब्जेक्ट कोड फ़ाइल में बदलकर ऐसा करता है, जो कि .o में समाप्त होने वाली फ़ाइल होती है जिसमें स्रोत कोड का बाइनरी संस्करण होता है। ऑब्जेक्ट कोड सीधे निष्पादन योग्य नहीं है, हालांकि। निष्पादन योग्य बनाने के लिए, आपको सभी लाइब्रेरी फ़ंक्शंस के लिए कोड भी जोड़ना होगा जो फ़ाइल में #include d थे (यह घोषणाओं को शामिल करने के समान नहीं है, जो कि #include करता है)। यह लिंकर का काम है।

सामान्य तौर पर, सी कंपाइलर को लागू करने का सही क्रम उस सिस्टम पर बहुत निर्भर करता है जिसका आप उपयोग कर रहे हैं। यहां हम GCC कंपाइलर का उपयोग कर रहे हैं, हालांकि यह ध्यान दिया जाना चाहिए कि कई और कंपाइलर मौजूद हैं:

% gcc -Wall -c foo.c

% OS 'कमांड प्रॉम्प्ट है। यह संकलक को फ़ाइल foo.c पर प्री-प्रोसेसर चलाने के लिए कहता है और फिर इसे ऑब्जेक्ट कोड फ़ाइल foo.o में संकलित करता है। -c विकल्प का अर्थ है स्रोत कोड फ़ाइल को ऑब्जेक्ट फ़ाइल में संकलित करना, लेकिन लिंकर को लागू करना नहीं। यह ऑप्शन -c POSIX सिस्टम पर उपलब्ध है, जैसे कि Linux या macOS; अन्य सिस्टम अलग सिंटैक्स का उपयोग कर सकते हैं।

यदि आपका पूरा कार्यक्रम एक स्रोत कोड फ़ाइल में है, तो आप इसके बजाय ऐसा कर सकते हैं:

% gcc -Wall foo.c -o foo

यह संकलक को foo.c पर प्री-प्रोसेसर को चलाने के लिए कहता है, इसे संकलित करता है और फिर इसे एक निष्पादन योग्य बनाता है जिसे foo कहा जाता है। -o विकल्प बताता है कि लाइन पर अगला शब्द बाइनरी एक्ज़ीक्यूटेबल फ़ाइल (प्रोग्राम) का नाम है। यदि आप -o निर्दिष्ट नहीं करते हैं, (यदि आप सिर्फ gcc foo.c टाइप करते हैं), तो निष्पादन योग्य को ऐतिहासिक कारणों के लिए a.out नाम दिया जाएगा।

सामान्य तौर पर कंपाइलर एक .c फाइल को एक एक्जीक्यूटेबल में परिवर्तित करते समय चार चरण लेता है:

  1. पूर्व-प्रसंस्करण - आपके .c फ़ाइल में #include निर्देशों और #define मैक्रो को .c रूप से विस्तारित करता है
  2. संकलन - प्रोग्राम को असेंबली में कनवर्ट करता है (आप -S विकल्प जोड़कर कंपाइलर को इस चरण पर रोक सकते हैं)
  3. विधानसभा - विधानसभा को मशीन कोड में परिवर्तित करता है
  4. लिंकेज - निष्पादन योग्य बनाने के लिए ऑब्जेक्ट कोड को बाहरी पुस्तकालयों से जोड़ता है

यह भी ध्यान दें कि जिस कंपाइलर का हम उपयोग कर रहे हैं उसका नाम GCC है, जो संदर्भ के आधार पर "GNU C कंपाइलर" और "GNU कंपाइलर कलेक्शन" दोनों के लिए है। अन्य C कंपाइलर मौजूद हैं। के लिए यूनिक्स की तरह ऑपरेटिंग सिस्टम, उनमें से कई नाम है cc , "सी संकलक" है, जो अक्सर कुछ अन्य संकलक करने के लिए एक प्रतीकात्मक कड़ी है। लिनक्स सिस्टम पर, cc अक्सर GCC के लिए एक उपनाम है। MacOS या OS-X पर, यह क्लैंग की ओर इशारा करता है।

POSIX मानकों वर्तमान में जनादेश c99 एक सी संकलक के नाम के रूप में - यह डिफ़ॉल्ट रूप से C99 मानक का समर्थन करता है। संकलक के रूप में POSIX के पूर्व संस्करणों ने c89 को अनिवार्य किया। POSIX यह भी आज्ञा देता है कि यह संकलक उन विकल्पों -c और -o समझता है, जिनका हमने ऊपर उपयोग किया था।


नोट: दोनों gcc उदाहरणों में मौजूद -Wall विकल्प संकलक को संदिग्ध निर्माणों के बारे में चेतावनी छापने के लिए कहता है, जिसकी दृढ़ता से अनुशंसा की जाती है। अन्य चेतावनी विकल्पों , जैसे -Wextra को जोड़ना भी एक अच्छा विचार है।

अनुवाद के चरण

सी 2011 स्टैंडर्ड के अनुसार, the5.1.1.2 ट्रांसलेशन चरणों में सूचीबद्ध, सोर्स कोड टू प्रोग्राम इमेज (जैसे, एग्जीक्यूटेबल) का अनुवाद 8 ऑर्डर किए गए चरणों में होने के लिए सूचीबद्ध है।

  1. स्रोत फ़ाइल इनपुट स्रोत चरित्र सेट (यदि आवश्यक हो) के लिए मैप किया गया है। इस चरण में ट्रिग्राफ को बदल दिया जाता है।
  2. निरंतरता लाइनों (लाइनों के साथ अंत \ ) अगली पंक्ति के साथ spliced रहे हैं।
  3. स्रोत कोड को व्हॉट्सएप और प्रीप्रोसेसिंग टोकन में पार्स किया गया है।
  4. प्रीप्रोसेसर लागू किया जाता है, जो निर्देशों को निष्पादित करता है, मैक्रोज़ का विस्तार करता है, और प्रैग्मस लागू करता है। प्रत्येक स्रोत फ़ाइल #include द्वारा खींची गई अनुवाद 1 चरण 4 से गुजरती है (यदि आवश्यक हो तो पुनरावर्ती)। सभी पूर्वप्रक्रमक संबंधित निर्देश तब हटा दिए जाते हैं।
  5. स्रोत चरित्र सेट चरित्र स्थिरांक और स्ट्रिंग शाब्दिक मान को निष्पादन वर्ण सेट पर मैप किया जाता है।
  6. एक दूसरे से सटे स्ट्रिंग शाब्दिक रूप से समवर्ती होते हैं।
  7. स्रोत कोड को टोकन में पार्स किया गया है, जिसमें अनुवाद इकाई शामिल है।
  8. बाहरी संदर्भ हल किए जाते हैं, और प्रोग्राम छवि बनाई जाती है।

सी कंपाइलर का कार्यान्वयन कई चरणों को एक साथ जोड़ सकता है, लेकिन परिणामी छवि को अभी भी व्यवहार करना चाहिए जैसे कि ऊपर सूचीबद्ध क्रम में उपरोक्त चरण अलग-अलग हुए थे।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow