zoukankan      html  css  js  c++  java
  • c语言中三个点的解释 : variadic

    3.6 Variadic Macros

    A macro can be declared to accept a variable number of arguments much as a function can. The syntax for defining the macro is similar to that of a function. Here is an example:

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

    This kind of macro is called variadic. When the macro is invoked, all the tokens in its argument list after the last named argument (this macro has none), including any commas, become the variable argument. This sequence of tokens replaces the identifier __VA_ARGS__ in the macro body wherever it appears. Thus, we have this expansion:

         eprintf ("%s:%d: ", input_file, lineno)
              ==>  fprintf (stderr, "%s:%d: ", input_file, lineno)
    

    The variable argument is completely macro-expanded before it is inserted into the macro expansion, just like an ordinary argument. You may use the ‘#’ and ‘##’ operators to stringify the variable argument or to paste its leading or trailing token with another token. (But see below for an important special case for ‘##’.)

    If your macro is complicated, you may want a more descriptive name for the variable argument than __VA_ARGS__. CPP permits this, as an extension. You may write an argument name immediately before the ‘...’; that name is used for the variable argument. The eprintf macro above could be written

         #define eprintf(args...) fprintf (stderr, args)
    

    using this extension. You cannot use __VA_ARGS__ and this extension in the same macro.

    You can have named arguments as well as variable arguments in a variadic macro. We could define eprintf like this, instead:

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

    This formulation looks more descriptive, but unfortunately it is less flexible: you must now supply at least one argument after the format string. In standard C, you cannot omit the comma separating the named argument from the variable arguments. Furthermore, if you leave the variable argument empty, you will get a syntax error, because there will be an extra comma after the format string.

         eprintf("success!
    ", );
              ==> fprintf(stderr, "success!
    ", );
    

    GNU CPP has a pair of extensions which deal with this problem. First, you are allowed to leave the variable argument out entirely:

         eprintf ("success!
    ")
              ==> fprintf(stderr, "success!
    ", );
    

    Second, the ‘##’ token paste operator has a special meaning when placed between a comma and a variable argument. If you write

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

    and the variable argument is left out when the eprintf macro is used, then the comma before the ‘##’ will be deleted. This does not happen if you pass an empty argument, nor does it happen if the token preceding ‘##’ is anything other than a comma.

         eprintf ("success!
    ")
              ==> fprintf(stderr, "success!
    ");
    

    The above explanation is ambiguous about the case where the only macro parameter is a variable arguments parameter, as it is meaningless to try to distinguish whether no argument at all is an empty argument or a missing argument. CPP retains the comma when conforming to a specific C standard. Otherwise the comma is dropped as an extension to the standard.

    The C standard mandates that the only place the identifier __VA_ARGS__ can appear is in the replacement list of a variadic macro. It may not be used as a macro name, macro argument name, or within a different type of macro. It may also be forbidden in open text; the standard is ambiguous. We recommend you avoid using it except for its defined purpose.

    Variadic macros became a standard part of the C language with C99. GNU CPP previously supported them with a named variable argument (‘args...’, not ‘...’ and __VA_ARGS__), which is still supported for backward compatibility.

  • 相关阅读:
    python疑难问题---5、二维列表初始化
    python疑难问题---4、python文件读写
    心得体悟帖---200701(你以为后面比当下好,其实还真的不一定)
    心得体悟帖---200701(《隐秘的角落》成熟的孩子小白)
    div垂直居中 css div盒子上下垂直居中
    iOS 7 新版微信 URL 不支持跳转 App Store 的解决方案
    HTML5 LocalStorage 本地存储
    WDCP是什么 关于WDCP的详细介绍
    前端框架用哪个好
    GWT 实现文件上传和下载
  • 原文地址:https://www.cnblogs.com/PhoenixMY/p/6237385.html
Copyright © 2011-2022 走看看