#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Apakah mungkin untuk menggabungkan STR3 == "s1"? Anda dapat melakukan ini dengan meneruskan args ke fungsi Makro lainnya. Tetapi apakah ada cara langsung?
c++
c
c-preprocessor
tvr
sumber
sumber
Jawaban:
Jika keduanya adalah string, Anda bisa melakukan:
Praprosesor secara otomatis menggabungkan string yang berdekatan.
EDIT:
Seperti disebutkan di bawah ini, bukan preprocessor tetapi kompiler yang melakukan penggabungan.
sumber
L"a"
dan"b"
mendapatkanL"ab"
, tetapi Anda dapat menggabungkanL"a"
danL"b"
mendapatkanL"ab"
.Anda tidak memerlukan solusi semacam itu untuk string literal, karena mereka digabungkan pada tingkat bahasa, dan itu tidak akan berfungsi karena "s" "1" bukan token preprocessor yang valid.
[Sunting: Menanggapi komentar "Hanya untuk dicatat" yang salah di bawah ini yang sayangnya menerima beberapa suara positif, saya akan mengulangi pernyataan di atas dan mengamati bahwa fragmen program
menghasilkan pesan kesalahan ini dari fase pra-pemrosesan gcc: kesalahan: menempelkan "" s "" dan "" 1 "" tidak memberikan token pra-pemrosesan yang valid
]
Namun, untuk penempelan token umum, coba ini:
Kemudian, misalnya, keduanya
PPCAT_NX(s, 1)
danPPCAT(s, 1)
menghasilkan pengenals1
, kecuali jikas
didefinisikan sebagai makro, dalam hal iniPPCAT(s, 1)
menghasilkan<macro value of s>1
.Melanjutkan tema adalah makro ini:
Kemudian,
Sebaliknya,
sumber
"s""1"
valid dalam C (dan C ++). Mereka adalah dua token (string literal) yang akan disatukan oleh kompiler dan ancaman sebagai satu token."s""1" isn't a valid token
- itu benar; itu, seperti yang Anda katakan, dua token. Tetapi menyatukannya dengan ## akan membuatnya menjadi token praproses tunggal , bukan dua token, sehingga compiler tidak akan melakukan penggabungan, melainkan lexer akan menolaknya (bahasa ini memerlukan diagnostik).STRINGIZE_NX(whatever occurs here)
berkembang menjadi "apa pun yang terjadi di sini", terlepas dari definisi makro apa pun untuk apa pun, yang terjadi, atau di sini.if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
- itu salah, dan tidak seperti ujian Anda. Anda berusaha keras untuk tidak memahami atau melakukan ini dengan benar, dan saya tidak akan menanggapi Anda lebih jauh.Petunjuk:
STRINGIZE
Makro di atas keren, tetapi jika Anda membuat kesalahan dan argumennya bukan makro - Anda memiliki kesalahan ketik pada namanya, atau lupa#include
pada file header - maka kompilator akan dengan senang hati memasukkan nama makro yang diklaim ke dalam string tanpa kesalahan.Jika Anda bermaksud agar argumen ke
STRINGIZE
selalu makro dengan nilai C normal, makaakan mengembangkannya sekali dan memeriksa validitasnya, membuangnya, lalu mengembangkannya lagi menjadi string.
Butuh beberapa saat bagi saya untuk mencari tahu mengapa
STRINGIZE(ENOENT)
berakhir sebagai"ENOENT"
alih-alih"2"
... Saya tidak memasukkanerrno.h
.sumber
,
operator yang tepat. :)((1),"1") "." ((2),"2")
bukan hanya "1" "." "2")STRINGIZE
definisi aslinya ,"The value of ENOENT is " STRINGIZE(ENOENT)
berfungsi, sedangkan"The value of ENOENT is" STRINGIZE_EXPR(X)
menghasilkan kesalahan.