diff options
author | Tom Tromey <tom@tromey.com> | 2017-11-13 20:17:42 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2017-11-13 20:17:42 +0000 |
commit | fb771b9dad6ef78a985353128cea48e620eb4324 (patch) | |
tree | d94251e8c98cb3a0a9bfd711707dea469e857c6b /gcc/doc | |
parent | 4d85d480272fb7331924f04534e0f5f14b60421e (diff) | |
download | gcc-fb771b9dad6ef78a985353128cea48e620eb4324.zip gcc-fb771b9dad6ef78a985353128cea48e620eb4324.tar.gz gcc-fb771b9dad6ef78a985353128cea48e620eb4324.tar.bz2 |
Implement __VA_OPT__
This implements __VA_OPT__, a new preprocessor feature added in C++2A.
The paper can be found here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0306r4.html
gcc/ChangeLog
* doc/cpp.texi (Variadic Macros): Document __VA_OPT__.
gcc/testsuite/ChangeLog
* c-c++-common/cpp/va-opt-pedantic.c: New file.
* c-c++-common/cpp/va-opt.c: New file.
* c-c++-common/cpp/va-opt-error.c: New file.
libcpp/ChangeLog
* pch.c (cpp_read_state): Set n__VA_OPT__.
* macro.c (vaopt_state): New class.
(_cpp_arguments_ok): Check va_opt flag.
(replace_args, create_iso_definition): Use vaopt_state.
* lex.c (lex_identifier_intern): Possibly issue errors for
__VA_OPT__.
(lex_identifier): Likewise.
(maybe_va_opt_error): New function.
* internal.h (struct lexer_state) <va_args_ok>: Update comment.
(struct spec_nodes) <n__VA_OPT__>: New field.
* init.c (struct lang_flags) <va_opt>: New field.
(lang_defaults): Add entries for C++2A. Update all entries for
va_opt.
(cpp_set_lang): Initialize va_opt.
* include/cpplib.h (struct cpp_options) <va_opt>: New field.
* identifiers.c (_cpp_init_hashtable): Initialize n__VA_OPT__.
From-SVN: r254707
Diffstat (limited to 'gcc/doc')
-rw-r--r-- | gcc/doc/cpp.texi | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 8cafb65..94437d5 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1675,20 +1675,27 @@ macro. We could define @code{eprintf} like this, instead: @end smallexample @noindent -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. +This formulation looks more descriptive, but historically it was less +flexible: you had to supply at least one argument after the format +string. In standard C, you could not omit the comma separating the +named argument from the variable arguments. (Note that this +restriction has been lifted in C++2a, and never existed in GNU C; see +below.) + +Furthermore, if you left the variable argument empty, you would have +gotten a syntax error, because there would have been an extra comma +after the format string. @smallexample eprintf("success!\n", ); @expansion{} fprintf(stderr, "success!\n", ); @end smallexample -GNU CPP has a pair of extensions which deal with this problem. First, -you are allowed to leave the variable argument out entirely: +This has been fixed in C++2a, and GNU CPP also has a pair of +extensions which deal with this problem. + +First, in GNU CPP, and in C++ beginning in C++2a, you are allowed to +leave the variable argument out entirely: @smallexample eprintf ("success!\n") @@ -1696,8 +1703,24 @@ eprintf ("success!\n") @end smallexample @noindent -Second, the @samp{##} token paste operator has a special meaning when -placed between a comma and a variable argument. If you write +Second, C++2a introduces the @code{@w{__VA_OPT__}} function macro. +This macro may only appear in the definition of a variadic macro. If +the variable argument has any tokens, then a @code{@w{__VA_OPT__}} +invocation expands to its argument; but if the variable argument does +not have any tokens, the @code{@w{__VA_OPT__}} expands to nothing: + +@smallexample +#define eprintf(format, @dots{}) \\ + fprintf (stderr, format __VA_OPT__(,) __VA_ARGS__) +@end smallexample + +@code{@w{__VA_OPT__}} is also available in GNU C and GNU C++. + +Historically, GNU CPP has also had another extension to handle the +trailing comma: the @samp{##} token paste operator has a special +meaning when placed between a comma and a variable argument. Despite +the introduction of @code{@w{__VA_OPT__}}, this extension remains +supported in GNU CPP, for backward compatibility. If you write @smallexample #define eprintf(format, @dots{}) fprintf (stderr, format, ##__VA_ARGS__) @@ -1730,6 +1753,9 @@ 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. +Likewise, C++ forbids @code{@w{__VA_OPT__}} anywhere outside the +replacement list of a variadic macro. + Variadic macros became a standard part of the C language with C99. GNU CPP previously supported them with a named variable argument |