जीसीसी डंप प्रीप्रोसेसर परिभाषित करता है


248

क्या कमांड लाइन से इसके प्रीप्रोसेसर डिफाइन को डंप करने के लिए gcc / g ++ का कोई तरीका है? मैं की तरह मतलब बातें __GNUC__, __STDC__, और इतने पर।

जवाबों:


304

हां, -E -dM-c के बजाय विकल्पों का उपयोग करें। उदाहरण (स्टडआउट के लिए उन्हें आउटपुट):

 gcc -dM -E - < /dev/null

C ++ के लिए

 g++ -dM -E -x c++ - < /dev/null

से जीसीसी मैनुअल :

सामान्य आउटपुट के बजाय, पूर्वनिर्मित मैक्रोज़ सहित प्रीप्रोसेसर के निष्पादन के दौरान परिभाषित सभी मैक्रोज़ के लिए `# डिडाइन 'निर्देशों की एक सूची तैयार करें। यह आपको यह पता लगाने का एक तरीका देता है कि प्रीप्रोसेसर के आपके संस्करण में क्या पूर्वनिर्धारित है। मान लें कि आपके पास कोई फ़ाइल foo.h, कमांड नहीं है

touch foo.h; cpp -dM foo.h

सभी पूर्वनिर्धारित मैक्रोज़ दिखाएगा।

यदि आप -E विकल्प के बिना -dM का उपयोग करते हैं, -dM को -fdump-rtl-mach के पर्याय के रूप में व्याख्या किया जाता है।


4
gcc उन प्रणालियों पर मौजूद है जहाँ / dev / null का अर्थ कुछ भी नहीं है।
पावेल पी

4
@Pavel तब आप एक खाली फ़ाइल का उपयोग कर सकते हैं, या तो gcc या प्रीप्रोसेसर - cpp के साथ।
दार्शनिक

16
मैंने वैकल्पिक उत्तर के रूप में अधिक पोर्टेबल दृष्टिकोण जोड़ा: echo | gcc -dM -E -खिड़कियों पर भी काम करता है।
पावेल पी।

4
क्या यह निर्धारित करना संभव है कि कहां (यानी, किस फाइल में) उन डिफाइन से आया है?
ईडीएम

2
वैकल्पिक रूप से, विंडोज पर, cpp -dM -E - < NULउपयोग किया जा सकता है।
रेने न्यफेनेगर

78

मैं आमतौर पर इसे इस तरह से करता हूं:

$ gcc -dM -E - < /dev/null

ध्यान दें कि कुछ प्रीप्रोसेसर परिभाषित कमांड लाइन विकल्पों पर निर्भर हैं - आप उपरोक्त कमांड लाइन में संबंधित विकल्पों को जोड़कर इनका परीक्षण कर सकते हैं। उदाहरण के लिए, यह देखने के लिए कि कौन से SSE3 / SSE4 विकल्प डिफ़ॉल्ट रूप से सक्षम हैं:

$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1

और फिर -msse4निर्दिष्ट होने पर इसकी तुलना करें :

$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1

इसी तरह आप देख सकते हैं कि कमांड लाइन विकल्पों के दो अलग-अलग सेटों के बीच कौन से विकल्प अलग-अलग हैं, उदाहरण के लिए अनुकूलन स्तर -O0(कोई नहीं) और -O3(पूर्ण) के लिए प्रीप्रोसेसर परिभाषित करें :

$ gcc -dM -E -O0 - < /dev/null > /tmp/O0.txt
$ gcc -dM -E -O3 - < /dev/null > /tmp/O3.txt
$ sdiff -s /tmp/O0.txt /tmp/O3.txt 
#define __NO_INLINE__ 1        <
                               > #define __OPTIMIZE__ 1

45

देर से जवाब - मुझे अन्य उत्तर उपयोगी लगे - और थोड़ा अतिरिक्त जोड़ना चाहते थे।


मैं एक विशेष हेडर फ़ाइल से आने वाले प्रीप्रोसेसर मैक्रोज़ को कैसे डंप करूं?

echo "#include <sys/socket.h>" | gcc -E -dM -

या (सुझाव के लिए @ मीमेडिया को धन्यवाद):

gcc -E -dM -include sys/socket.h - < /dev/null

विशेष रूप से, मैं यह देखना चाहता था कि मेरे सिस्टम पर SOMAXCONN को क्या परिभाषित किया गया है। मुझे पता है कि मैं सिर्फ मानक हेडर फ़ाइल खोल सकता था, लेकिन कभी-कभी मुझे हेडर फ़ाइल स्थानों को खोजने के लिए थोड़ा खोज करना पड़ता है। इसके बजाय मैं सिर्फ इस वन-लाइनर का उपयोग कर सकता हूं:

$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$ 

1
आप उपयोग कर सकते -include से बचने के पाइप के लिए संकलक विकल्प
Mymedia

31

साधारण दृष्टिकोण ( gcc -dM -E - < /dev/null) gcc के लिए ठीक काम करता है लेकिन g ++ के लिए विफल रहता है। हाल ही में मुझे C ++ 11 / C ++ 14 फीचर के लिए एक परीक्षण की आवश्यकता थी। उनके संबंधित मैक्रो नामों के लिए सिफारिशें https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations पर प्रकाशित की जाती हैं । परंतु:

g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates

हमेशा विफल रहता है, क्योंकि यह चुपचाप सी-ड्राइवरों को आमंत्रित करता है (जैसे कि द्वारा आह्वान किया गया है gcc)। आप इसे gcc के विरुद्ध इसके आउटपुट की तुलना करके या g ++ - विशिष्ट कमांड लाइन विकल्प (जैसे -std = c ++ 11) जोड़कर देख सकते हैं जो त्रुटि संदेश का उत्सर्जन करता है cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C

क्योंकि (गैर C ++) जीसीसी "टेम्प्लेट्स अलायस" का समर्थन कभी नहीं करेगा (देखें http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ) आपको -x c++विकल्प जोड़ना होगा C ++ कंपाइलर के मंगलाचरण को बाध्य करें ( -x c++खाली डमी फ़ाइल के बजाय विकल्पों का उपयोग करने का श्रेय yuyichao पर जाएं, नीचे देखें):

g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates

कोई आउटपुट नहीं होगा क्योंकि g ++ (संशोधन 4.9.1, डिफ़ॉल्ट से -dd = gnu ++ 98) डिफ़ॉल्ट रूप से C ++ 11-फीचर्स को सक्षम नहीं करता है। ऐसा करने के लिए, का उपयोग करें

g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates

जो अंत में उपज देता है

#define __cpp_alias_templates 200704

यह देखते हुए कि g ++ 4.9.1 के साथ "टेम्प्लेट एलियासेस" का समर्थन करता है -std=c++11


7
आपको डमी फ़ाइल का उपयोग करने की आवश्यकता नहीं है। जीसीसी -xतर्क का समर्थन करता है इसलिए g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cppकाम करना चाहिए।
युयुचो

@yuyichao आपका धन्यवाद, इससे उपयोग करना आसान हो गया है। मुझे -x विकल्प के बारे में पता नहीं था। अपनी टिप्पणी को उकेरा और मूल उत्तर में एकीकृत किया।
हरमनक

23

एक पोर्टेबल दृष्टिकोण जो लिनक्स या विंडोज पर समान रूप से अच्छी तरह से काम करता है (जहां कोई / देव / शून्य नहीं है):

echo | gcc -dM -E -

C ++ के लिए आप उपयोग कर सकते हैं ( c++11जो भी संस्करण आप उपयोग करते हैं उसके साथ बदलें ):

echo | gcc -x c++ -std=c++11 -dM -E -

यह gpro को प्रीप्रोसेस स्टिन (जो प्रतिध्वनि द्वारा निर्मित होता है) और सभी प्रीप्रोसेसर डिफाइन (खोज -dletters) प्रिंट करके बताता है । आप को पता है परिभाषित करता है क्या कर रहे हैं चाहते हैं जोड़ा है जब आप एक हेडर फाइल आप उपयोग कर सकते हैं शामिल हैं -dDविकल्प जो -dM के समान है लेकिन पूर्व-निर्धारित मैक्रो शामिल नहीं है:

echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -

ध्यान दें, हालांकि, वह खाली इनपुट अभी भी -dDविकल्प के साथ बहुत सारे परिभाषित करता है।


6
@rubenvb यह अप्रासंगिक है। इस बिंदु पर cmd लाइन है जो खिड़कियों पर समान रूप से अच्छी तरह से काम करती है और कम से कम यूनिक्स है। यदि आप उपयोग करते हैं NUL, तो आप वापस एक वर्ग में आते हैं: यह उन प्रणालियों पर काम नहीं करेगा जिनके पास यह नहीं है।
पावेल पी।

2
C ++ के लिए पूर्ण उत्तर जोड़ते हुए, विंडोज और लिनक्स दोनों पर काम करता है (हालाँकि sortथोड़ा अलग व्यवहार करता है):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Xeverous

यह गिट-बैश में खाली आउटपुट पैदा करता है।
लेनार्ट रोलैंड

@ LennartRolland क्या यह gcc है? मेरे git-bash में मैं gcc नहीं चला सकता
Pavel P

@ अंवल I mtw32 gcc का उपयोग करता है जो विंडोज़ के लिए Qt5 बाइनरी वितरण के साथ आता है।
लेनार्ट रोलैंड

3

एक बड़ी परियोजना में काम करते समय जिसमें जटिल बिल्ड सिस्टम होता है और जहां जीसीसी / जी ++ कमांड को सीधे प्राप्त करना (या संशोधित करना) कठिन होता है, मैक्रो विस्तार के परिणाम को देखने का एक और तरीका है। बस मैक्रो को फिर से परिभाषित करें, और आपको आउटपुट निम्नलिखित के अनुरूप मिलेगा:

file.h: note: this is the location of the previous definition
#define MACRO current_value

मैं देख रहा हूं कि इसके लिए क्या चेतावनी ध्वज का उपयोग किया जाता है। क्या आप जानते हैं ?
वेलग्रिव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.