GCC preprocessor dump mendefinisikan

Jawaban:

304

Ya, gunakan -E -dMopsi bukan -c. Contoh (menampilkannya ke stdout):

 gcc -dM -E - < /dev/null

Untuk C ++

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

Dari manual gcc :

Alih-alih output normal, buatlah daftar arahan `#define 'untuk semua makro yang didefinisikan selama eksekusi preprocessor, termasuk makro yang telah ditentukan sebelumnya. Ini memberi Anda cara untuk mengetahui apa yang telah ditentukan dalam versi preprosesor Anda. Dengan asumsi Anda tidak memiliki file foo.h, perintah

touch foo.h; cpp -dM foo.h

akan menampilkan semua makro yang telah ditentukan.

Jika Anda menggunakan -dM tanpa opsi -E, -dM ditafsirkan sebagai sinonim untuk -fdump-rtl-mach.

filant
sumber
4
gcc ada pada sistem di mana / dev / null tidak berarti apa-apa.
Pavel P
4
@Pavel maka Anda dapat menggunakan file kosong, baik dengan gcc atau preprocessor - cpp.
philant
16
Saya menambahkan pendekatan yang lebih portabel sebagai jawaban alternatif: echo | gcc -dM -E -bekerja di windows juga.
Pavel P
4
Apakah mungkin untuk menentukan dari mana (yaitu, di file mana) definisi itu berasal?
edam
2
Atau, di Windows, cpp -dM -E - < NULbisa digunakan.
René Nyffenegger
78

Saya biasanya melakukannya dengan cara ini:

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

Perhatikan bahwa beberapa definisi preprocessor bergantung pada opsi baris perintah - Anda dapat mengujinya dengan menambahkan opsi yang relevan ke baris perintah di atas. Misalnya, untuk melihat opsi SSE3 / SSE4 mana yang diaktifkan secara default:

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

dan kemudian membandingkan ini ketika -msse4ditentukan:

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

Demikian pula Anda dapat melihat opsi mana yang berbeda antara dua set opsi baris perintah yang berbeda, misalnya membandingkan definisi preprosesor untuk tingkat optimisasi -O0(tidak ada) dan -O3(penuh):

$ 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
Paul R
sumber
45

Jawaban telat - Saya menemukan jawaban lain bermanfaat - dan ingin menambahkan sedikit ekstra.


Bagaimana cara membuang makro preprosesor yang berasal dari file header tertentu?

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

atau (terima kasih kepada @mymedia atas sarannya):

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

Secara khusus, saya ingin melihat apa yang SOMAXCONN didefinisikan pada sistem saya. Saya tahu saya bisa membuka file header standar, tetapi kadang-kadang saya harus mencari sedikit untuk menemukan lokasi file header. Alih-alih, saya hanya dapat menggunakan one-liner ini:

$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$ 
Trauma Digital
sumber
1
Anda dapat menggunakan -Masukkan pilihan compiler untuk pipa menghindari
Mymedia
31

Pendekatan sederhana ( gcc -dM -E - < /dev/null) berfungsi dengan baik untuk gcc tetapi gagal untuk g ++. Baru-baru ini saya membutuhkan tes untuk fitur C ++ 11 / C ++ 14. Rekomendasi untuk nama makro yang sesuai diterbitkan di https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recomendations . Tapi:

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

selalu gagal, karena secara diam - diam memanggil driver-C (seolah-olah dipanggil oleh gcc). Anda dapat melihat ini dengan membandingkan outputnya dengan gcc atau dengan menambahkan g ++ - opsi baris perintah khusus seperti (-std = c ++ 11) yang memancarkan pesan kesalahan cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C.

Karena (yang bukan C ++) gcc tidak akan pernah mendukung "Templates Alias" (lihat http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ) Anda harus menambahkan -x c++opsi ke paksa pemanggilan kompiler C ++ (Kredit untuk menggunakan -x c++opsi alih-alih file dummy kosong pergi ke yuyichao, lihat di bawah):

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

Tidak akan ada output karena g ++ (revisi 4.9.1, default ke -std = gnu ++ 98) tidak mengaktifkan C ++ 11-fitur secara default. Untuk melakukannya, gunakan

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

yang akhirnya menghasilkan

#define __cpp_alias_templates 200704

mencatat bahwa g ++ 4.9.1 mendukung "Templates Alias" ketika dipanggil dengan -std=c++11.

hermannk
sumber
7
Anda tidak harus menggunakan file dummy. GCC mendukung -xargumen sehingga g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cppseharusnya berfungsi.
yuyichao
@ yuyichao Terima kasih, ini membuatnya lebih mudah digunakan. Saya tidak mengetahui opsi -x. Membarui komentar Anda dan mengintegrasikannya ke dalam jawaban asli.
hermannk
23

Pendekatan portabel yang bekerja dengan baik di Linux atau Windows (di mana tidak ada / dev / null):

echo | gcc -dM -E -

Untuk c ++ Anda dapat menggunakan (ganti c++11dengan versi apa pun yang Anda gunakan):

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

Ia bekerja dengan memberitahu gcc untuk preprocess stdin (yang diproduksi oleh echo) dan mencetak semua definisi preprocessor (mencari -dletters). Jika Anda ingin tahu definisi apa yang ditambahkan saat Anda memasukkan file header, Anda dapat menggunakan -dDopsi yang mirip dengan -dM tetapi tidak menyertakan makro yang telah ditentukan:

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

Perhatikan, bagaimanapun, bahwa input kosong masih menghasilkan banyak definisi dengan -dDopsi.

Pavel P
sumber
6
@rubenvb tidak relevan. intinya adalah memiliki garis cmd yang berfungsi sama baiknya di windows dan unix setidaknya. Jika Anda menggunakan NUL, Anda kembali ke titik awal: itu tidak akan bekerja pada sistem yang tidak memilikinya.
Pavel P
2
menambahkan jawaban lengkap untuk C ++, berfungsi pada Windows dan Linux (meskipun sortberperilaku sedikit berbeda):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Xeverous
Ini menghasilkan output kosong di git-bash.
Lennart Rolland
@LennartRolland apakah ada gcc? Dalam git-bash saya, saya tidak bisa menjalankan gcc
Pavel P
@ Pavel Saya menggunakan mingw32 gcc yang dilengkapi dengan distribusi biner Qt5 untuk windows.
Lennart Rolland
3

Saat bekerja dalam proyek besar yang memiliki sistem build kompleks dan di mana sulit untuk mendapatkan (atau memodifikasi) perintah gcc / g ++ secara langsung, ada cara lain untuk melihat hasil ekspansi makro. Cukup mendefinisikan ulang makro, dan Anda akan mendapatkan hasil yang serupa dengan yang berikut:

file.h: note: this is the location of the previous definition
#define MACRO current_value
Piotr Pałucki
sumber
Saya mencari bendera peringatan apa yang digunakan untuk itu. Apakah anda tahu
Welgriv