__VA_ARGS__ 與 ## 小檔案

 

我大致整理出要點, 供急功近利的新手參考.

1. __VA_ARGS__ 顧名思義, 就是一個可變的參數.

例如: #define ABC(format,…)   printf(format, __VA_ARGS__);

注意最後這個分號.

2. 假如實際參數是 0 的話, 會發生下面的問題

 ABC(“%s") –> printf(“%s",);

為了除去這個逗號, 可以用 ## 來提示 compiler.

例如: #define ABC(format,…)   printf(format, ##__VA_ARGS__);

3. 由於 __VA_ARGS__ 有點礙眼, 所以它可以被抽象化成一個變數.

例如: #define ABC(format,…)   printf(format, ##arg);

4. 以上講的是 macro 的使用, 在 function 當中一樣可以用

例如: int function(char *argv, …)

這個可以用來處理 command line 參數的情況, 因為參數可多可少.

function 當中可以用 ##__VA_ARGS__ 來傳遞 … 所代表的值給其他 function.

或是透過 va_list, va_start, va_arg, va_end 這四個標準函式庫把 argv 裡面放的東西一一取出來. 用法參見:

http://www.cplusplus.com/reference/clibrary/cstdarg/va_start.html 有使用範例

http://ehome.hifly.to/showthread.php?s=&threadid=329 有原始 macro code, 也有範例, 呃…, 還有一連串的討論.

———————————————

關於如何巧妙運用 __VA_ARGS_, 在網路上的這篇文章, 有很好的介紹, 大家可以去看.

http://www.jeffhung.net/blog/articles/jeffhung/1012/ 

__VA_ARGS__ 與 ## 小檔案 有 “ 2 則迴響 ”

  1. 3. 由於 __VA_ARGS__ 有點礙眼, 所以它可以被抽象化成一個變數.

    例如: #define ABC(format,…)   printf(format, ##arg);

    第三条应该是

            #define ABC(format, arg…)   printf(format, ##arg);

    1. 謝謝您的提醒. ##arg 和 _VA_ARGS_ 確實不完全相等.

      關於這個部分, 有個網頁寫得很完整, 我就抄過來了. 

      http://bytes.com/topic/c/answers/218257-macros-variable-number-arguments

      ……

      Yes and No.

      The specific syntax being used is GCC specific. ANSI C (1999 standard)
      has variable argument macros with a different syntax (which modern GCC
      supports).

      Old GCC syntax…
      #define P_VAR(output, string, args…)
      fprintf (output, “This is “string"n", ##args)

      The “##" in the above macro is GCCs method of dealing with the case where
      the variable part of the macro is empty. It has the effect of deleting the
      comma just prior to the “##" when args is empty.
      ANSI C and new GCC syntax
      #define P_VAR(output, …)
      fprintf (output, “This is “string"n", __VA_ARGS__)

      This definition of P_VAR has the identical expansion as the previous definition
      of P_VAR. Both require a minimum of 2 parameters when being expanded.

      The Old GCC version has the advantage that it’s closer to what you expect
      from experience with printf() and company, but suffers from the kludge
      needed when the variable part of the macro is empty.

      The ANSI C version doesn’t have the “empty kludge", but requires one more
      parameter than the number of named parameters. For example let’s say that
      I want to create a “log" macro that is used in the exact same fashion as
      printf() except it sends all output to log_file instead of stdout. The
      desired macro would look like:

      #define log(…) fprintf(log_file, __VA_ARGS__)

      And yes, the log macro would require at least 1 parameter in order to be
      legal just as printf() requires at least 1 parameter.

      Using the old GCC style the macro would be

      #define log(format, args…) fprintf(log_file, format, ##args)

      I would suggest that you use the new ANSI method of variable argument macros
      instead of the old GCC style since it is likely to be supported by more
      compilers in the future.

回覆給anson 取消回覆