Ada masalah terkenal dengan arg kosong untuk makro variadic di C99.
contoh:
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
Penggunaan di BAR()
atas memang salah menurut standar C99, karena akan diperluas ke:
printf("this breaks!",);
Perhatikan tanda koma - tidak bisa digunakan.
Beberapa kompiler (mis: Visual Studio 2010) akan dengan tenang menyingkirkan koma jejak itu untuk Anda. Kompiler lain (misalnya: GCC) mendukung meletakkan ##
di depan __VA_ARGS__
, seperti:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
Tetapi apakah ada cara yang sesuai standar untuk mendapatkan perilaku ini? Mungkin menggunakan beberapa makro?
Saat ini, ##
versi ini tampaknya cukup didukung (setidaknya pada platform saya), tetapi saya lebih suka menggunakan solusi yang sesuai standar.
Pre-emptive: Saya tahu saya hanya bisa menulis fungsi kecil. Saya mencoba melakukan ini menggunakan makro.
Sunting : Ini adalah contoh (walaupun sederhana) mengapa saya ingin menggunakan BAR ():
#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);
Ini secara otomatis menambahkan baris baru ke pernyataan logging BAR () saya, dengan asumsi fmt
selalu merupakan C-string yang dikutip ganda. Ini TIDAK mencetak baris baru sebagai printf terpisah (), yang menguntungkan jika logging-buffered dan berasal dari berbagai sumber secara tidak sinkron.
__VA_OPT__
kata kunci. Ini sudah "diadopsi" oleh C ++, jadi saya berharap C akan mengikutinya. (tidak tahu apakah itu berarti itu dilacak cepat ke C ++ 17 atau jika itu ditetapkan untuk C ++ 20 sekalipun)
BAR
daripadaFOO
di tempat pertama?