簡體   English   中英

為什么我的可變參數宏不能正確接受任何參數?

[英]Why won't my variadic macro accept no arguments correctly?

在參數數量上重載宏

https://codecraft.co/2014/11/25/variadic-macros-tricks/

我一直在看上面的兩個鏈接,試圖使以下代碼起作用:

#define _GET_NUMBER(_0, _1, _2, _3, _4, _5, NAME, ...) NAME
#define OUTPUT_ARGS_COUNT(...) _GET_NUMBER(_0, ##__VA_ARGS__, 5, 4, 3, 2, 1, 0)

...

cout << OUTPUT_ARGS_COUNT("HelloWorld", 1.2) << endl;
cout << OUTPUT_ARGS_COUNT("HelloWorld") << endl;
cout << OUTPUT_ARGS_COUNT() << endl;

這將編譯,運行並提供以下輸出:

2
1
1

我一生無法弄清楚為什么OUTPUT_ARGS_COUNT()調用給我的是1而不是0。我對我要使用的代碼有很好的了解,但是對我來說這還是一個有點希臘,所以我猜盡管我確實從堆棧溢出鏈接中復制並粘貼了示例代碼,但我可能未正確應用某些內容。

我正在使用g ++ 5.4.0 20160609進行編譯。

您可以向我指出的任何想法或其他資源將不勝感激。

您可以在http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html上看到:

其次,'##'令牌粘貼運算符放在逗號和變量參數之間時具有特殊含義。 如果你寫

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

並且在使用eprintf宏時省略了變量參數,然后將刪除'##'之前的逗號。 如果您傳遞一個空參數,則不會發生這種情況,如果'##'之前的標記不是逗號,也不會發生這種情況。

eprintf ("success!\n")
 → fprintf(stderr, "success!\n");

上面的解釋對於唯一的宏參數是可變參數參數的情況是模棱兩可的,因為試圖區分根本沒有參數是空參數還是缺失參數毫無意義。 符合特定的C標准時,CPP保留逗號。 否則,逗號將作為標准的擴展名被刪除。

因此,(除非使用了適當的擴展名) OUTPUT_ARGS_COUNT()被計為1個空參數(逗號與##__VA_ARGS__保持在一起)。

C標准規定

如果宏定義中的標識符列表不以省略號結尾,則為[...]。 否則, 調用中的參數要比宏定義中的參數多(不包括...)

C2011 6.10.3 / 4 ;重點添加)

C ++ 11包含與第16.3 / 4段相同的語言。

那么,在這兩種情況下,如果您的宏調用被解釋為具有零參數,則您的程序將是不一致的。 另一方面,預處理器確實識別並支持空的宏參數,即由零個預處理令牌組成的參數。 因此,原則上,無參數和單個空參數之間存在歧義,但實際上,只有后者的解釋會導致程序一致。

因此,g ++選擇后者的解釋(另一個答案為此引用了其文檔)是合理和適當的,但是如果您希望代碼具有可移植性,則依靠它是不安全的。 采用替代解釋的編譯器的行為可能有所不同,可能是通過提供您期望的行為,也可能是通過拒絕代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM