Saya mencoba mencari tahu versi Boost apa yang menurut kode saya digunakan. Saya ingin melakukan sesuatu seperti ini:
#error BOOST_VERSION
tetapi preprocessor tidak memperluas BOOST_VERSION.
Saya tahu saya dapat mencetaknya pada saat run-time dari program, dan saya tahu saya dapat melihat output dari preprocessor untuk menemukan jawabannya. Saya merasa memiliki cara melakukan ini selama kompilasi dapat bermanfaat.
macros
c-preprocessor
boost-preprocessor
Jim Hunziker
sumber
sumber
Jawaban:
Saya tahu bahwa ini masih lama setelah kueri asli, tetapi ini mungkin masih berguna.
Ini dapat dilakukan di GCC menggunakan operator stringify "#", tetapi memerlukan dua tahap.
Nilai makro kemudian dapat ditampilkan dengan:
Lihat: 3.4 Stringifikasi dalam dokumentasi online gcc.
Bagaimana itu bekerja:
Praprosesor memahami string yang dikutip dan menanganinya secara berbeda dari teks normal. Rangkaian string adalah contoh dari perlakuan khusus ini. Pragma pesan membutuhkan argumen yang berupa string yang dikutip. Jika ada lebih dari satu komponen ke argumen maka semuanya harus berupa string sehingga penggabungan string dapat diterapkan. Praprosesor tidak pernah dapat berasumsi bahwa string tanpa tanda kutip harus diperlakukan seolah-olah dikutip. Jika ya maka:
tidak akan dikompilasi.
Sekarang pertimbangkan:
yang setara dengan
Ini menyebabkan peringatan preprocessor karena abc (unquoted) tidak dapat digabungkan dengan string sebelumnya.
Sekarang perhatikan preprocessor stringize (Yang pernah disebut stringifikasi, link dalam dokumentasi telah diubah untuk mencerminkan terminologi yang direvisi. (Kedua istilah tersebut, kebetulan, sama-sama menjijikkan. Istilah yang benar, tentu saja, stringifaction. Bersiaplah untuk memperbarui tautan Anda.)). Ini hanya bertindak pada argumen makro dan menggantikan argumen yang tidak diperluas dengan argumen yang diapit tanda kutip ganda. Jadi:
akan memberikan nilai yang identik ke s1 dan s2. Jika Anda menjalankan gcc -E, Anda dapat melihat ini di keluaran. Mungkin STR akan lebih baik diberi nama seperti ENQUOTE.
Ini memecahkan masalah menempatkan kutipan di sekitar item yang tidak dikutip, masalahnya sekarang adalah, jika argumennya adalah makro, makro tidak akan diperluas. Inilah mengapa makro kedua dibutuhkan. XSTR memperluas argumennya, lalu memanggil STR untuk memasukkan nilai yang diperluas ke dalam tanda kutip.
sumber
__IPHONE_9_3
.BOOST_PP_STRINGIZE
tampaknya solusi yang sangat baik untuk C ++, tetapi tidak untuk C biasa.Inilah solusi saya untuk GNU CPP:
Definisi di atas menghasilkan:
Untuk variabel "didefinisikan sebagai interger" , "didefinisikan sebagai string" , dan "ditentukan tetapi tidak ada nilai" , keduanya berfungsi dengan baik. Hanya untuk variabel "tidak ditentukan" , mereka ditampilkan persis sama dengan nama variabel asli. Anda harus terbiasa - atau mungkin seseorang dapat memberikan solusi yang lebih baik.
sumber
DEFINED_INT=(sizeof(MY_STRUCT))
, tanpasizeof
operator dievaluasi.sizeof
, namun, masih penasaran apakah ada cara cerdas untuk mencapai ini.)#define masks {0xff, 0xaf, 0x0f}
Jika Anda menggunakan Visual C ++, Anda dapat menggunakan
#pragma message
:Edit: Terima kasih kepada LB untuk tautannya
Rupanya, padanan GCC (tidak diuji):
sumber
BOOST_PP_STRINGIZE
yang bagus dan pendek serta dapat di-copy / paste.Sejauh yang saya tahu '#error' hanya akan mencetak string, sebenarnya Anda bahkan tidak perlu menggunakan tanda kutip .
Sudahkah Anda mencoba menulis berbagai kode yang salah secara sengaja menggunakan "BOOST_VERSION"? Mungkin sesuatu seperti "blah [BOOST_VERSION] = foo;" akan memberi tahu Anda sesuatu seperti "string literal 1.2.1 tidak dapat digunakan sebagai alamat array". Ini tidak akan menjadi pesan kesalahan yang bagus, tapi setidaknya itu akan menunjukkan kepada Anda nilai yang relevan. Anda dapat bermain-main sampai Anda menemukan kesalahan kompilasi yang memberi tahu Anda nilainya.
sumber
std::vector<BOOST_VERSION>;
di gcc 4.4.1. Terima kasih!Tanpa dorongan:
definisikan makro yang sama lagi dan compiler DIRINYA akan memberikan peringatan.
Dari peringatan Anda dapat melihat lokasi definisi sebelumnya.
file vi dari definisi sebelumnya.
sumber
__cplusplus
.Di Microsoft C / C ++, Anda dapat menggunakan bawaan
_CRT_STRINGIZE()
untuk mencetak konstanta. Banyakstdafx.h
file saya berisi beberapa kombinasi dari ini:dan menghasilkan sesuatu seperti ini:
sumber
Berfungsi bahkan jika
preprocess to file
diaktifkan, meskipun ada token yang tidak valid:sumber
Build error: #include expects "FILENAME" or <FILENAME>
. Mendesah.'
:*** WARNING C318 IN LINE 2 OF test.c: can't open file '::*/`'
Anda juga dapat memproses file sumber dan melihat untuk apa nilai preprocessor mengevaluasi.
sumber
Apakah Anda sedang mencari
Tidak bagus jika BOOST_VERSION adalah string, seperti yang saya asumsikan, tetapi mungkin juga ada bilangan bulat individual yang ditentukan untuk bilangan mayor, minor, dan revisi.
sumber
#if VARIABLE == 123
pernyataan dengan cepat dan penyorotan sintaks memberi tahu saya apakah itu nilai yang saya pikirkan atau tidak ...Melihat keluaran dari preprocessor adalah hal yang paling mendekati jawaban yang Anda minta.
Saya tahu Anda telah mengecualikannya (dan cara lain), tetapi saya tidak yakin mengapa. Anda memiliki masalah yang cukup spesifik untuk dipecahkan, tetapi Anda belum menjelaskan mengapa salah satu metode "normal" tidak bekerja dengan baik untuk Anda.
sumber
Anda dapat menulis program yang mencetak
BOOST_VERSION
dan mengkompilasi serta menjalankannya sebagai bagian dari sistem build Anda. Kalau tidak, saya pikir Anda kurang beruntung.sumber
BOOST_VERSION didefinisikan dalam file header boost version.hpp.
sumber
Lihat juga dokumentasi Boost, mengenai bagaimana Anda menggunakan makro:
Mengacu ke
BOOST_VERSION
, dari http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros :sumber
Alih-alih #error, coba definisikan ulang makro, tepat sebelum digunakan. Kompilasi akan gagal dan kompilator akan memberikan nilai saat ini yang menurutnya berlaku untuk makro.
#define BOOST_VERSION bla
sumber