प्रीप्रोसेसिंग के बाद आउटपुट सी कोड प्राप्त कर सकते हैं?


104

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

क्या gcc (या लिनक्स में आमतौर पर उपलब्ध कोई अन्य टूल) इस लाइब्रेरी को पढ़ सकता है लेकिन आउटपुट C कोड जिसमें प्रीप्रोसेसिंग को जो कुछ भी परिवर्तित किया गया है और एक मानव द्वारा पठनीय है?


प्रीप्रोसेड कोड के पास अब कोई प्रीप्रोसेसर निर्देश नहीं होगा, लेकिन मुझे पूरा यकीन है कि यह प्रीप्रोसेस होने से पहले की तुलना में बहुत कम पठनीय होगा ...
एलेक्स डब्ल्यू

2
@ एलेक्स डब्ल्यू - यह पूरी तरह से निर्भर करता है कि कोड लिखने वाले लोगों ने प्रीप्रोसेसर का कितना दुरुपयोग किया है।
नकली नाम

1
कृपया अपना स्वीकृत उत्तर यहां बदलने पर विचार करें। gcc -Eइसके साथ काम करने के लिए लाइन को फिर से लिखने की तुलना में अधिक उपयोगी है cpp
ग्रे

जवाबों:


193

हाँ। -Eविकल्प को पास करें । यह प्रीप्रोसेड सोर्स कोड को आउटपुट करेगा।


12
यदि आपके कंपाइलर कमांड में पहले से ही एक पैरामीटर है जैसे -o something.oआप भी इसे बदलना चाह सकते हैं -o something.i। अन्यथा .oफ़ाइल में प्रीप्रोसेस्ड आउटपुट होगा ।
Tor Klingberg

@TorKlingberg क्या मैं एक बार में कई फ़ाइलों के लिए ऐसा कर सकता हूँ?
user2808264

@ user2808264gcc -E file1.c file2.c ...
मैथ्यू

68

cpp प्रीप्रोसेसर है।

cpp filename.cप्रीप्रोसेड कोड को आउटपुट करने के लिए चलाएँ , या बेहतर, इसे एक फ़ाइल के साथ रीडायरेक्ट करें cpp filename.c > filename.preprocessed


2
मुझे लगता है कि यह सबसे अच्छा जवाब है क्योंकि यह सीधे cpp को दर्शाता है। लिनक्स सिस्टम (कम से कम मंज़रो) के लिए डिफ़ॉल्ट रूप से भी लगता है। मुझे इस आदेश से वैसे ही परिणाम मिलते हैं। diffफ़ाइलों में कोई अंतर नहीं है। यह आपके मैक्रोज़ में त्रुटियों की तलाश करने वाले कोड को प्रीप्रॉसेस करने के लिए एक उपयोगी तरीका भी है। महान प्रश्न और एक महान जवाब (IALCTHW)।
lee8oi

17

मैं एक पूर्वप्रक्रमक (html फ़ाइलों के लिए) के रूप में gcc का उपयोग कर रहा हूं। यह वही करता है जो आप चाहते हैं। यह "# -" निर्देशों का विस्तार करता है, फिर एक पठनीय फ़ाइल को आउटपुट करता है। (अन्य सी / एचटीएमएल प्रीप्रोसेसर के किसी ने मुझे ऐसा करने की कोशिश की है - वे लाइनों को समेटते हैं, विशेष वर्णों पर चोक करते हैं, आदि) मान लें कि आपने जीसीसी स्थापित किया है, कमांड लाइन है:

gcc -E -xc -P -C -traditional-cpp code_before.cpp> code_after.cpp

('Cpp' होना जरूरी नहीं है।) http://www.cs.tut.fi/~jkorpela/html/cpre.html पर इस उपयोग का उत्कृष्ट वर्णन है ।

"-Traditional-cpp" व्हॉट्सएप और टैब को संरक्षित करता है।


बहुत धन्यवाद, यह अजगर cffi cdef उत्पन्न करने के लिए बहुत उपयोगी है!
अमीरो

13

-save-temps

यह ध्यान में रखने के लिए एक और अच्छा विकल्प है:

gcc -save-temps -c -o main.o main.c

main.c

#define INC 1

int myfunc(int i) {
    return i + INC;
}

और अब, सामान्य आउटपुट के अलावा main.o, वर्तमान कार्यशील निर्देशिका में निम्न फाइलें भी शामिल हैं:

  • main.i वांछित पसंदीदा फ़ाइल है:

    # 1 "main.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 31 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 32 "<command-line>" 2
    # 1 "main.c"
    
    
    int myfunc(int i) {
        return i + 1;
    }
    
  • main.s एक बोनस है :-) और इसमें शामिल विधानसभा है:

        .file   "main.c"
        .text
        .globl  myfunc
        .type   myfunc, @function
    myfunc:
    .LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -4(%rbp)
        movl    -4(%rbp), %eax
        addl    $1, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
    .LFE0:
        .size   myfunc, .-myfunc
        .ident  "GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0"
        .section    .note.GNU-stack,"",@progbits
    

यदि आप इसे बड़ी संख्या में फ़ाइलों के लिए करना चाहते हैं, तो इसके बजाय उपयोग करने पर विचार करें:

 -save-temps=obj

जो मध्यवर्ती फ़ाइलों को -oवर्तमान कार्य निर्देशिका के बजाय ऑब्जेक्ट आउटपुट के समान निर्देशिका में सहेजता है , इस प्रकार संभावित बेसनेम टकराव से बचता है।

इस विकल्प पर लाभ यह -Eहै कि किसी भी बिल्ड स्क्रिप्ट में इसे जोड़ना आसान है, बिना बिल्ड में ज्यादा दखल दिए।

इस विकल्प के बारे में एक और अच्छी बात यह है कि यदि आप जोड़ते हैं -v:

gcc -save-temps -c -o main.o -v main.c

यह वास्तव में बदसूरत अस्थायी के बजाय उपयोग की जा रही स्पष्ट फाइलों को दिखाता है /tmp, इसलिए यह जानना आसान है कि क्या चल रहा है, जिसमें प्रीप्रोसेसिंग / संकलन / असेंबली चरण शामिल हैं:

/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu main.c -mtune=generic -march=x86-64 -fpch-preprocess -fstack-protector-strong -Wformat -Wformat-security -o main.i
/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -fpreprocessed main.i -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase-strip main.o -version -fstack-protector-strong -Wformat -Wformat-security -o main.s
as -v --64 -o main.o main.s

उबंटू में परीक्षण 19.04 amd64, GCC 8.3.0।


1
अधिक से अधिक सुरुचिपूर्ण -E क्योंकि मैं निर्माण स्क्रिप्ट के समग्र व्यवहार को बदलने के बिना CFLAGS में सिर्फ-टेम्प-ऐड जोड़ सकता हूं। धन्यवाद!
EvertW

यह वास्तव में बहुत उपयोगी है, और एकल फ़ाइलों के लिए ई बहुत सुविधाजनक है।
सबिन सेबस्टियन


1

मान लीजिए कि हमारे पास Message.cpp या .c फ़ाइल के रूप में एक फ़ाइल है

चरण 1: प्रीप्रोसेसिंग (तर्क-ई)

g ++ -E। \ Message.cpp> P1

उत्पन्न P1 फ़ाइल ने मैक्रोज़ और हेडर फ़ाइल सामग्री का विस्तार किया है और टिप्पणियां छीन ली गई हैं।

चरण 2: असम्बद्ध फ़ाइल को असेंबली में अनुवाद करें (तर्क -S)। यह कार्य कंपाइलर द्वारा किया जाता है

g ++ -S। \ Message.cpp

एक कोडांतरक (ASM) उत्पन्न होता है (Message.s)। इसमें सभी असेंबली कोड है।

चरण 3: विधानसभा कोड का ऑब्जेक्ट कोड में अनुवाद करें। नोट: Step.2 में Message.s उत्पन्न किया गया था। g ++ -c। \ Message.s

Message.o नाम के साथ एक ऑब्जेक्ट फ़ाइल उत्पन्न होती है। यह बाइनरी फॉर्म है।

चरण 4: ऑब्जेक्ट फ़ाइल को लिंक करना। यह कार्य लिंकर द्वारा किया जाता है

g ++। \ Message.o -o MessageApp

एक exe फ़ाइल MessageApp.exe यहाँ उत्पन्न होती है।

#include <iostream>
using namespace std;

 //This a sample program
  int main()
{
cout << "Hello" << endl;
 cout << PQR(P,K) ;
getchar();
return 0;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.