GCC döküm önişlemcisi tanımlar


Yanıtlar:


304

Evet, -E -dM-c yerine seçenekleri kullanın. Örnek (stdout'a gönderir):

 gcc -dM -E - < /dev/null

C ++ için

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

Gönderen gcc kılavuzu :

Normal çıktı yerine, önceden tanımlanmış makrolar dahil olmak üzere önişlemcinin yürütülmesi sırasında tanımlanan tüm makrolar için bir #define yönergesi listesi oluşturun. Bu, önişlemci sürümünüzde önceden tanımlanmış olanı bulmanın bir yolunu sunar. Foo.h dosyanız olmadığını varsayarsak, komut

touch foo.h; cpp -dM foo.h

önceden tanımlanmış tüm makroları gösterir.

-E seçeneği olmadan -dM kullanırsanız, -dM, -fdump-rtl-mach ile eş anlamlı olarak yorumlanır.


4
gcc, / dev / null öğesinin hiçbir şey ifade etmediği sistemlerde bulunur.
Pavel P

4
@Pavel sonra gcc veya önişlemci - cpp ile boş bir dosya kullanabilirsiniz.
hayırsever

16
Alternatif bir cevap olarak daha taşınabilir bir yaklaşım ekledim: echo | gcc -dM -E -Windows üzerinde de çalışır.
Pavel P

4
Bu tanımların nereden geldiğini (yani hangi dosyada) belirlemek mümkün müdür?
edam

2
Alternatif olarak, Windows üzerinde cpp -dM -E - < NULkullanılabilir.
René Nyffenegger

78

Genellikle bu şekilde yaparım:

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

Bazı önişlemci tanımlarının komut satırı seçeneklerine bağlı olduğunu unutmayın - yukarıdaki komut satırına ilgili seçenekleri ekleyerek bunları test edebilirsiniz. Örneğin, varsayılan olarak hangi SSE3 / SSE4 seçeneklerinin etkinleştirildiğini görmek için:

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

ve -msse4belirtildiğinde bunu karşılaştırın :

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

Benzer şekilde, iki farklı komut satırı seçeneği kümesi arasında hangi seçeneklerin farklılık gösterdiğini görebilirsiniz; örneğin, optimizasyon düzeyleri -O0(hiçbiri) ve -O3(tam) için önişlemci tanımlarını karşılaştırın :

$ 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

Geç cevap - Diğer cevapları yararlı buldum - ve biraz daha eklemek istedim.


Belirli bir başlık dosyasından gelen önişlemci makrolarını nasıl dökerim?

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

veya (öneri için @ mymedia'ya teşekkürler):

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

Özellikle, SOMAXCONN'un sistemimde neyi tanımladığını görmek istedim. Standart başlık dosyasını açabileceğimi biliyorum, ancak bazen başlık dosyası konumlarını bulmak için biraz araştırmam gerekiyor. Bunun yerine sadece bu tek astarı kullanabilirim:

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

1
Kullanabileceğiniz -Include derleyici önlemek borulara seçeneği
Mymedia

31

Basit yaklaşım ( gcc -dM -E - < /dev/null) gcc için iyi çalışır ancak g ++ için başarısız olur. Son zamanlarda bir C ++ 11 / C ++ 14 özelliği için bir test gerekli. İlgili makro adları için öneriler https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations adresinde yayınlanır . Fakat:

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

her zaman başarısız olur, çünkü sessizce C sürücülerini çağırır (sanki çağrılmış gibi gcc). Çıktısını gcc ile karşılaştırarak veya hata mesajını yayan (-std = c ++ 11) gibi g ++ 'a özgü komut satırı seçeneği ekleyerek bunu görebilirsiniz cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C.

(C ++ olmayan) gcc hiçbir zaman "Şablon Takma Adlarını" desteklemeyeceğinden (bkz. Http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ) -x c++seçeneğini eklemeniz gerekir . C ++ derleyicisinin çağrılmasını zorlayın ( -x c++boş bir kukla dosya yerine seçenekleri kullanma kredisi yuyichao'ya gidin, aşağıya bakın):

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

G ++ (düzeltme 4.9.1, varsayılan olarak -std = gnu ++ 98) C ++ 11 özelliklerini varsayılan olarak etkinleştirmediği için çıktı alınmayacaktır. Bunu yapmak için şunu kullanın:

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

sonunda nihayet

#define __cpp_alias_templates 200704

ile çağrıldığında g ++ 4.9.1'in "Şablon Takma Adları" nı desteklediğine dikkat edin -std=c++11.


7
Sahte bir dosya kullanmanıza gerek yoktur. GCC -xargümanı desteklemektedir, bu yüzden g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cppçalışması gerekir.
yuyichao

@yuyichao Teşekkürler, bu kullanımı kolaylaştırır. -X seçeneğinin farkında değildim. Yorumunuzu onayladı ve orijinal yanıta entegre etti.
hermannk

23

Linux veya Windows'da eşit derecede iyi çalışan taşınabilir bir yaklaşım (/ dev / null olmadığında):

echo | gcc -dM -E -

C ++ için kullanabilirsiniz (kullandığınız c++11sürümle değiştirin ):

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

Gcc'ye ön işlem stdin'e (echo tarafından üretilen) söylenmesini ve tüm önişlemci tanımlarının yazdırılmasını (arama -dletters) söyleyerek çalışır . Bir başlık dosyası eklediğinizde hangi tanımların eklendiğini bilmek istiyorsanız, -dD-dM'ye benzer ancak önceden tanımlanmış makrolar içermeyen seçeneği kullanabilirsiniz :

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

Bununla birlikte, boş girişin hala -dDseçenekle birlikte çok sayıda tanım ürettiğini unutmayın .


6
@rubenvb alakasız. asıl nokta, en azından pencerelerde ve unix'te eşit derecede iyi çalışan cmd çizgisine sahip olmaktır. Kullanırsanız NUL, bir kareye geri dönersiniz: sahip olmayan sistemlerde çalışmaz.
Pavel P

2
C ++ için tam cevap ekleyerek, hem Windows hem de Linux üzerinde çalışır ( sortbiraz farklı davranmasına rağmen ):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Xeverous

Bu git-bash'ta boş çıktı üretir.
Lennart Rolland

@LennartRolland'da gcc var mı? Git-bash'ımda gcc'yi çalıştıramıyorum
Pavel P

@pavel Windows için Qt5 ikili dağıtımıyla gelen mingw32 gcc kullanıyorum.
Lennart Rolland

3

Karmaşık yapı sistemi olan ve doğrudan gcc / g ++ komutunu almanın (veya değiştirmenin) zor olduğu büyük bir projede çalışırken, makro genişletmenin sonucunu görmenin başka bir yolu vardır. Sadece makroyu yeniden tanımlayın ve çıktıya aşağıdakine benzerlik kazandırın:

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

Bunun için hangi uyarı bayrağının kullanıldığını arıyorum. Biliyor musun ?
Welgriv
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.