Topic: Proposal to standardize __VA_NARGS__
Author: morwenn29@gmail.com
Date: Fri, 25 Oct 2013 11:36:08 -0700 (PDT)
Raw View
------=_Part_864_30043283.1382726168293
Content-Type: text/plain; charset=ISO-8859-1
The C++11 preprocessor inherited variadic macros from the C99 preprocessor.
When variadic macros are used, the user often wants to know
the exact number of variadic arguments that have been given to the macro.
The common trick to get the number of arguments is to use a macro,
usually named VA_NARGS or VA_NUM_ARGS which is defined as follows:
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N #define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
With this macro, the user can use get the numbers of arguments of a macro
with VA_NARGS(__VA_ARGS__).
However, the number of arguments is limited (maximum of 63 arguments) and
it does not work correctly if zero arguments are given.
Therefore, it might be great to require implementations to provide a macro
__VA_NARGS__ which resolves these two problems.
Moreover, I never saw it used with any other arguments than __VA_ARGS__ and
I don't think using it with other parameters will be useful anyway.
Therefore, instead of having it defined as a function-like macro, it could
be defined as a constant-like macro which would hold the number of
variadic arguments in the current variadic macro.
Also, if the idea is juged interesting, it would also be better to propose
__VA_NARGS__ to the C standard committee too. What do you think of
such a feature?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_864_30043283.1382726168293
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">The C++11 preprocessor inherited variadic macros from the =
C99 preprocessor. When variadic macros are used, the user often wants to kn=
ow<br>the exact number of variadic arguments that have been given to the ma=
cro. The common trick to get the number of arguments is to use a macro,<br>=
usually named VA_NARGS or VA_NUM_ARGS which is defined as follows:<br><br><=
pre style=3D"" class=3D"lang-c prettyprint prettyprinted"><code><span class=
=3D"com"> #define</span><span class=3D"pln"> VA_NARGS_IMPL</span><span c=
lass=3D"pun">(</span><span class=3D"pln">_1</span><span class=3D"pun">,</sp=
an><span class=3D"pln"> _2</span><span class=3D"pun">,</span><span class=3D=
"pln"> _3</span><span class=3D"pun">,</span><span class=3D"pln"> _4</span><=
span class=3D"pun">,</span><span class=3D"pln"> _5</span><span class=3D"pun=
">,</span><span class=3D"pln"> N</span><span class=3D"pun">,</span><span cl=
ass=3D"pln"> </span><span class=3D"pun">...)</span><span class=3D"pln"> N
</span><span class=3D"com"> #define</span><span class=3D"pln"> VA_NARGS<=
/span><span class=3D"pun">(...)</span><span class=3D"pln"> VA_NARGS_IMPL</s=
pan><span class=3D"pun">(</span><span class=3D"pln">__VA_ARGS__</span><span=
class=3D"pun">,</span><span class=3D"pln"> </span><span class=3D"lit">5</s=
pan><span class=3D"pun">,</span><span class=3D"pln"> </span><span class=3D"=
lit">4</span><span class=3D"pun">,</span><span class=3D"pln"> </span><span =
class=3D"lit">3</span><span class=3D"pun">,</span><span class=3D"pln"> </sp=
an><span class=3D"lit">2</span><span class=3D"pun">,</span><span class=3D"p=
ln"> </span><span class=3D"lit">1</span><span class=3D"pun">)</span></code>=
</pre><br>With this macro, the user can use get the numbers of arguments of=
a macro with <code><span class=3D"pln">VA_NARGS</span><span class=3D"pun">=
(__VA_ARGS__).<br></span></code><br>However, the number of arguments is lim=
ited (maximum of 63 arguments) and it does not work correctly if zero argum=
ents are given.<br>Therefore, it might be great to require implementations =
to provide a macro __VA_NARGS__ which resolves these two problems.<br><br>M=
oreover, I never saw it used with any other arguments than __VA_ARGS__ and =
I don't think using it with other parameters will be useful anyway.<br>Ther=
efore, instead of having it defined as a function-like macro, it could be d=
efined as a constant-like macro which would hold the number of<br>variadic =
arguments in the current variadic macro.<br><br>Also, if the idea is juged =
interesting, it would also be better to propose __VA_NARGS__ to the C stand=
ard committee too. What do you think of<br>such a feature?<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_864_30043283.1382726168293--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Fri, 25 Oct 2013 11:47:03 -0700
Raw View
--089e0163427a21c60404e9952d61
Content-Type: text/plain; charset=ISO-8859-1
On Fri, Oct 25, 2013 at 11:36 AM, <morwenn29@gmail.com> wrote:
> The C++11 preprocessor inherited variadic macros from the C99
> preprocessor. When variadic macros are used, the user often wants to know
> the exact number of variadic arguments that have been given to the macro.
> The common trick to get the number of arguments is to use a macro,
> usually named VA_NARGS or VA_NUM_ARGS which is defined as follows:
>
> #define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N #define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
>
>
> With this macro, the user can use get the numbers of arguments of a macro
> with VA_NARGS(__VA_ARGS__).
>
> However, the number of arguments is limited (maximum of 63 arguments) and
> it does not work correctly if zero arguments are given.
> Therefore, it might be great to require implementations to provide a macro
> __VA_NARGS__ which resolves these two problems.
>
> Moreover, I never saw it used with any other arguments than __VA_ARGS__
> and I don't think using it with other parameters will be useful anyway.
> Therefore, instead of having it defined as a function-like macro, it could
> be defined as a constant-like macro which would hold the number of
> variadic arguments in the current variadic macro.
>
> Also, if the idea is juged interesting, it would also be better to propose
> __VA_NARGS__ to the C standard committee too. What do you think of
> such a feature?
>
Seems reasonable to me, but I'd suggest proposing it to the C committee
first.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0163427a21c60404e9952d61
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Fri, Oct 25, 2013 at 11:36 AM, <span dir=3D"ltr"><<=
a href=3D"mailto:morwenn29@gmail.com" target=3D"_blank">morwenn29@gmail.com=
</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_qu=
ote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">The C++11 preprocessor inherited variadic macros from the =
C99 preprocessor. When variadic macros are used, the user often wants to kn=
ow<br>the exact number of variadic arguments that have been given to the ma=
cro. The common trick to get the number of arguments is to use a macro,<br>
usually named VA_NARGS or VA_NUM_ARGS which is defined as follows:<br><br><=
pre><code><span> #define</span><span> VA_NARGS_IMPL</span><span>(</span>=
<span>_1</span><span>,</span><span> _2</span><span>,</span><span> _3</span>=
<span>,</span><span> _4</span><span>,</span><span> _5</span><span>,</span><=
span> N</span><span>,</span><span> </span><span>...)</span><span> N
</span><span> #define</span><span> VA_NARGS</span><span>(...)</span><spa=
n> VA_NARGS_IMPL</span><span>(</span><span>__VA_ARGS__</span><span>,</span>=
<span> </span><span>5</span><span>,</span><span> </span><span>4</span><span=
>,</span><span> </span><span>3</span><span>,</span><span> </span><span>2</s=
pan><span>,</span><span> </span><span>1</span><span>)</span></code></pre>
<br>With this macro, the user can use get the numbers of arguments of a mac=
ro with <code><span>VA_NARGS</span><span>(__VA_ARGS__).<br></span></code><b=
r>However, the number of arguments is limited (maximum of 63 arguments) and=
it does not work correctly if zero arguments are given.<br>
Therefore, it might be great to require implementations to provide a macro =
__VA_NARGS__ which resolves these two problems.<br><br>Moreover, I never sa=
w it used with any other arguments than __VA_ARGS__ and I don't think u=
sing it with other parameters will be useful anyway.<br>
Therefore, instead of having it defined as a function-like macro, it could =
be defined as a constant-like macro which would hold the number of<br>varia=
dic arguments in the current variadic macro.<br><br>Also, if the idea is ju=
ged interesting, it would also be better to propose __VA_NARGS__ to the C s=
tandard committee too. What do you think of<br>
such a feature?</div></blockquote><div><br></div><div>Seems reasonable to m=
e, but I'd suggest proposing it to the C committee first.=A0</div></div=
></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0163427a21c60404e9952d61--
.
Author: morwenn29@gmail.com
Date: Sat, 26 Oct 2013 04:07:49 -0700 (PDT)
Raw View
------=_Part_84_11537927.1382785669140
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Le vendredi 25 octobre 2013 20:47:03 UTC+2, Richard Smith a =E9crit :
>
>
> Seems reasonable to me, but I'd suggest proposing it to the C committee=
=20
> first.=20
>
I'm ok with proposing it to the C committee first, but I couldn't find how=
=20
to do so. I know how to submit and discuss proposals for WG21,
but I can't find how to submit proposals or discuss them with WG14.=20
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_84_11537927.1382785669140
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Le vendredi 25 octobre 2013 20:47:03 UTC+2, Richard Smith =
a =E9crit :<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div><div class=3D"gmail_quote"><div><br></div><div>Seems reasonable to =
me, but I'd suggest proposing it to the C committee first. </div></div=
></div></div></blockquote><div><br>I'm ok with proposing it to the C commit=
tee first, but I couldn't find how to do so. I know how to submit and discu=
ss proposals for WG21,<br>but I can't find how to submit proposals or discu=
ss them with WG14. <br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_84_11537927.1382785669140--
.
Author: George Makrydakis <irrequietus@gmail.com>
Date: Sun, 27 Oct 2013 19:05:32 +0200
Raw View
--bcaec5430bcac7209904e9bbfd68
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On 10/25/2013 09:36 PM, morwenn29@gmail.com wrote:
The C++11 preprocessor inherited variadic macros from the C99 preprocessor.
When variadic macros are used, the user often wants to know
the exact number of variadic arguments that have been given to the macro.
The common trick to get the number of arguments is to use a macro,
usually named VA_NARGS or VA_NUM_ARGS which is defined as follows:
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N #define
VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
That macro and its kin are well known to be incomplete for several
reasons, while also not easily extensible. There are much better ways to do
this and people familiar with C99 preprocessor metaprogramming are quite
aware of how to implement and use such constructs even to extremes that go
beyond the purpose of this post. For the sake of record, the technique you
are referring to relies on variations of Laurent Deniau's PP_NARG in
https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s,<https://gro=
ups.google.com/forum/#%21topic/comp.std.c/d-6Mj5Lko_s>although
other authors have done similar things in the past.
With this macro, the user can use get the numbers of arguments of a macro
with VA_NARGS(__VA_ARGS__).
However, the number of arguments is limited (maximum of 63 arguments) and
it does not work correctly if zero arguments are given.
Therefore, it might be great to require implementations to provide a macro
__VA_NARGS__ which resolves these two problems.
There is more to this than actually discussed here but let's focus on the
simple aspect of counting macro arguments. Strictly speaking, there is no
such thing as "zero" arguments in function - like macro expansion, because
when "no arguments" are passed to a function - like macro whose parameters
in definition consist only of the ellipsis notation, they are collectively
treated as a single empty preprocessor token which itself is a single
argument!
This is because in C99 =A76.10.3p4 and C++11 =A716.3p4 it is stated that "t=
here
shall be more arguments in the invocation than there are parameters in the
macro definition (excluding the ...)" and following that segment we observe
that "including those arguments consisting of no preprocessor tokens".
Therefore, we can refer to the "empty" preprocessor token as something
quite tangible as a concept. Let's see this in a rather well known problem
as the one below:
#define VARMACRO_0(...)#define VARMACRO_1(x,...)
VARMACRO_0() // 16.3p4 provision covers it, -pedantic will not bother you=
..
VARMACRO_0(1) // Perfectly acceptable as per VARMACRO_0 definition.
VARMACRO_1(1) // Non - standard, this is a gnu extension, ellipsis
notation requires 1 more.
VARMACRO_1(1,) // This is _one_ standard - compliant way to invoke the
macro, but 2 args.
The problem here is, that the VARMACRO_0 function - like macro can be
invoked both as VARMACRO_0() and VARMACRO_0(1), with the hypothetical
__VA_NARGS__ having to expand to 1 in both cases which is obviously
*conceptually
correct* for the preprocessor (since it deals with the number of tokens and
the "empty" token is an argument itself) *but semantically
inacceptable*for the intended purpose of use, that is detecting that
the empty token is
the sole argument in the __VA_ARGS__ identifier.
As a consequence, the actual problem we are dealing with preprocessor -
wise, is to detect whether __VA_ARGS__ expands to an empty token or not.
Knowing when __VA_ARGS__ expands to the empty token is important as a
*fundamental
operation*, because using it in relatively simple recursive macro expansion
constructs, one can come up with the equivalent of __VA_NARGS__.
Having a way to detect whether __VA_ARGS__ expands to the "empty" token
would thus cover the two seemingly contrasting but completely legal
invocations of a VARMACRO_0 - like function - like macro. The importance of
empty argument detection is also analyzed in a post by Jens Gustedt at
https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/,
with which I agree to up a point.
Another clue to why __VA_ARGS__ expanding to the empty token or not is
important, has to do with trailing commas. This lead to GCC implementeing
", ##__VA_ARGS__" as an extension for "eating" the trailing comma when
__VA_ARGS__ is empty, while other compilers may use other solutions to
appeal to the developers requiring it. This leads to a lot of preprocessor
boilerplate for compiler checking when it happens.
Moreover, I never saw it used with any other arguments than __VA_ARGS__ and
I don't think using it with other parameters will be useful anyway.
Therefore, instead of having it defined as a function-like macro, it could
be defined as a constant-like macro which would hold the number of
variadic arguments in the current variadic macro.
Also, if the idea is juged interesting, it would also be better to propose
__VA_NARGS__ to the C standard committee too. What do you think of
such a feature?
--
I think that a constant identifier in the guise of __VA_EMPTY__ expanding
to a meaningful token for detecting empty - ness as well as dealing with
the need of the ", ##__VA_ARGS__" extension would be a better way to deal
with the problem as a whole, because it could be an opportunity to offer
something computationally more complete for preprocessor metaprogrammers
(the work of which made a lot of things possible when C++11 was not around,
just look at boost).
__VA_EMPTY__ 's expansion could be used to construct recursive macro
constructs that "count" arguments by resolving to meaningful expansions for
preprocessor metaprogrammers to use. Since the preprocessor (when
unassisted by metaprogramming implemented in it) has no way of actually
dealing with arithmetic and logical operations of constant expressions in
macro expansions (out of the #if directives), we would have to have a value
for __VA_EMPTY__ that is non - numerical.
I think that this hypothetical __VA_EMPTY__ identifier could thus expand to
an empty token when __VA_ARGS__ is an empty token itself, and to a comma
(i.e. ,) when for all other cases, for the reasons stated above. Comma
expansions and argument concatenations are among the very essential
techniques for preprocessor metaprogramming after all.
Thus, __VA_EMPTY__ in the end could be named as __VA_COMMA__ and it
should be an identifier present in the replacement list of a function -
like macro provided the ellipsis notation is used in its parameter
definition, just like __VA_ARGS__.
An inclusive example follows of how such a hypothetical __VA_COMMA__
identifier could be used in at least two different scenarios, that is in
counting macro arguments and dealing with trailing commas. I cannot stress
enough that this is fictional code since the __VA_COMMA__ identifier does
not exist, so after conceptualizing the abstraction please do report any
inconsistencies.
/** * *WARNING*: fictional C++ code for __VA_COMMA__ ! * * The
following is a more of a demonstration of a simple way to count macro
* arguments in function - like macros, had a __VA_COMMA__ identifier
been * available for __VA_ARGS__. __VA_COMMA__ is right now a
*fictional* constant * identifier, so do not attempt to actually use
it! * * *NOTE*: __VA_COMMA__ identifier convention used in this code.
* * The __VA_COMMA__ identifier can be present in the replacement
list of a * function - like macro only if it uses the ellipsis
notation in its * parameters. __VA_COMMA__ always expands to a single
comma (,) if and only if * __VA_ARGS__ does not expand to an empty
preprocessor token. * */
/** * This is far from ideal, but it serves its purpose. Implementing
a counter * macro for 0 to 3 arguments in __VA_ARGS__. Notice the use
of the fictional * __VA_COMMA__ object - like macro. */
#define VA_NARGS_HELP(...) __VA_COMMA__ 3, 2, 1, 0,#define
VA_NARGS(...) VA_NARGS__(__VA_ARGS__ VA_NARGS_HELP())#define
VA_NARGS__(...) VA_NARGS_(__VA_ARGS__)#define VA_NARGS_(_0, _1, _2,
_N, ...) _N
/** * We cannot just use (x,...) because of C++11 16.3p4. We want to
have at * least another argument passed (such as an "empty" one), that
is mandatory * for strict C99 preprocessor compliance. A few more
lines of preprocessor * can also implement a no - op for when LOGGER()
is invoked (perfectly * legal C++11, C99). Notice that __VA_COMMA__
expands to , if and only if * __VA_ARGS__ is not empty. The example is
inspired by Wikipedia's entry * on
http://en.wikipedia.org/wiki/Variadic_macro for the , ##__VA_ARGS__ *
GCC extension, but made consistent with 16.3p4. */
#define LOGGER(...) LOGGER_B(LOGGER_,
VA_NARGS(__VA_COMMA__))(__VA_ARGS__)#define LOGGER_B(a,b) LOGGER_C(a,
b)#define LOGGER_C(a,b,...) a ## b
/** * Our use of the VA_NARGS(__VA_COMMA__) means that if __VA_ARGS__
is not * the empty token, then because of __VA_COMMA__ it will expand
to 2. The * alternative, where __VA_ARGS__ is null, would expand it to
0, as above. * Thus, we need two different macros, one that works with
a single argument, * and one working with at least one argument,
because of the way the ellipsis * is forcing us to do function - like
macro invocation in C++11 and C99. */
#define LOGGER_2(fliteral, ...) \ fprintf(stderr, "%s(%d): "
fliteral "\n",__FILE__,__LINE__,__VA_ARGS__)
/** * Here, __VA_ARGS__ actually always expands to a single argument,
which * is analogous to fliteral because of how __VA_COMMA__ makes
VA_NARGS expand! */
#define LOGGER_0(...) \ fprintf(stderr, "%s(%d): " __VA_ARGS__
"\n", __FILE__,__LINE__)
VA_NARGS() // 0 : __VA_ARGS__ is empty, thus __VA_COMMA__ is empt=
y
VA_NARGS(a) // 1 : __VA_ARGS__ is NOT empty, thus __VA_COMMA__ is =
,
VA_NARGS(a,b) // 2 : __VA_ARGS__ is NOT empty, thus __VA_COMMA__ is =
,
VA_NARGS(a,b,c) // 3 : __VA_ARGS__ is NOT empty, thus __VA_COMMA__ is =
,
VA_NARGS(,) // 2 : __VA_ARGS__ is NOT empty, thus __VA_COMMA__ is =
,
// and right now it consists of 2 empty tokens!
LOGGER("too many balloons %d", 42) // OK! __VA_COMMA__ leads to LOGGER_2
LOGGER("just enough to go by") // OK! __VA_COMMA__ leads to LOGGER_0
Implementing __VA_COMMA__ would be trivial and it could also be used in far
more advanced constructs as a fundamental building block for computation,
just like the use of commas in preprocessor metaprogramming libraries like
in boost preprocessor by Vesa Karvonen and Paul Mensonides and Jens
Gustedt's P99.
Given the fact that no arithmetical and logical operations are required to
deduce the meaning of the expansion within the preprocessor and it being
versatile enough to be deployed in different scenarios, I think that we
should consider a __VA_COMMA__ identifier as a better option to just
__VA_NARGS__ since it seems to be computationally superior.
I am not arguing about whether __VA_NARGS__ alone could be used in order to
deal with the problems I have stated above (not without more complicated
constructs!), I am saying that I just do not believe that __VA_NARGS__ is
as important given that it becomes trivial when __VA_COMMA__ like the one
demonstrated above is available.
That of course, is just an opinion on a fictional concept and nothing more.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--bcaec5430bcac7209904e9bbfd68
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">
=20
=20
=20
<div text=3D"#000000" bgcolor=3D"#FFFFFF">
<div>On 10/25/2013 09:36 PM, <a href=3D"mailto:morwenn29@gmail.com" tar=
get=3D"_blank">morwenn29@gmail.com</a> wrote:<br>
</div>
<blockquote type=3D"cite">
<div dir=3D"ltr">The C++11 preprocessor inherited variadic macros
from the C99 preprocessor. When variadic macros are used, the
user often wants to know<br>
the exact number of variadic arguments that have been given to
the macro. The common trick to get the number of arguments is to
use a macro,<br>
usually named VA_NARGS or VA_NUM_ARGS which is defined as
follows:<br>
<br>
<pre><code><span> #define</span><span> VA_NARGS_IMPL</span><span=
>(</span><span>_1</span><span>,</span><span> _2</span><span>,</span><span> =
_3</span><span>,</span><span> _4</span><span>,</span><span> _5</span><span>=
,</span><span> N</span><span>,</span><span> </span><span>...)</span><span> =
N
</span><span> #define</span><span> VA_NARGS</span><span>(...)</span><spa=
n> VA_NARGS_IMPL</span><span>(</span><span>__VA_ARGS__</span><span>,</span>=
<span> </span><span>5</span><span>,</span><span> </span><span>4</span><span=
>,</span><span> </span><span>3</span><span>,</span><span> </span><span>2</s=
pan><span>,</span><span> </span><span>1</span><span>)</span></code></pre>
</div>
</blockquote>
=20
That macro and its kin are well known to be incomplete for several
reasons, while also not easily extensible. There are much better
ways to do this and people familiar with C99 preprocessor
metaprogramming are quite aware of how to implement=A0 and use such
constructs even to extremes that go beyond the purpose of this post. Fo=
r the sake of record, the technique
you are referring to relies on variations of Laurent Deniau's PP_NA=
RG in <a href=3D"https://groups.google.com/forum/#%21topic/comp.std.c/d-6Mj=
5Lko_s" target=3D"_blank">https://groups.google.com/forum/#!topic/comp.std.=
c/d-6Mj5Lko_s,</a>
although other authors have done similar things in the past.<br>
<blockquote type=3D"cite">
<div dir=3D"ltr">With this macro, the user can use get the numbers
of arguments of a macro with <code><span>VA_NARGS</span><span>(__VA=
_ARGS__).<br>
</span></code><br>
However, the number of arguments is limited (maximum of 63
arguments) and it does not work correctly if zero arguments are
given.<br>
Therefore, it might be great to require implementations to
provide a macro __VA_NARGS__ which resolves these two problems.<br>=
</div></blockquote>
There is more to this than actually discussed here but let's focus
on the simple aspect of counting macro arguments. Strictly speaking, th=
ere is no such thing as "zero" arguments in function - like macro
expansion, because when "no arguments" are passed to a functi=
on -
like macro whose parameters in definition consist only of the
ellipsis notation, they are collectively treated as a single empty prep=
rocessor
token which itself is a single argument!<br>
<br>
This is because in C99 =A76.10.3p4 and C++11 =A716.3p4 it is stated
that "there shall be more arguments in the invocation than there a=
re
parameters in the macro definition (excluding the <code>...</code>)&quo=
t; and following that segment we observe that
"including those arguments consisting of no preprocessor tokens&qu=
ot;. Therefore, we
can refer to the "empty" preprocessor token as something quit=
e tangible as a concept. Let's see this in a rather
well known problem as the one below:<br>
<pre style=3D"color:rgb(31,28,27)"><span style=3D"color:rgb(7,47,87)">#=
define VARMACRO_0(...)</span>
<span style=3D"color:rgb(7,47,87)">#define VARMACRO_1(x,...)</span>
VARMACRO_0() <span style=3D"color:rgb(137,136,135)">// 16.3p4 provision c=
overs it, -pedantic will not bother you.</span>
VARMACRO_0(<span style=3D"color:rgb(176,128,0)">1</span>) <span style=3D"c=
olor:rgb(137,136,135)">// Perfectly acceptable as per VARMACRO_0 definition=
..</span>
VARMACRO_1(<span style=3D"color:rgb(176,128,0)">1</span>) <span style=3D"c=
olor:rgb(137,136,135)">// Non - standard, this is a gnu extension, ellipsis=
notation requires 1 more.</span>
VARMACRO_1(<span style=3D"color:rgb(176,128,0)">1</span>,) <span style=3D"c=
olor:rgb(137,136,135)">// This is _one_ standard - compliant way to invoke =
the macro, but 2 args.</span></pre>
<br>
The
problem here is, that the VARMACRO_0 function - like macro can be
invoked both as VARMACRO_0() and VARMACRO_0(1), with the
hypothetical __VA_NARGS__ having to expand to 1 in both cases which
is obviously <b>conceptually correct</b> for the preprocessor (since it
deals with the number of tokens and the "empty" token is an a=
rgument
itself) <b>but semantically inacceptable</b> for the intended purpose o=
f use,
that is detecting that the empty token is the sole argument in the
__VA_ARGS__ identifier.<br>
<br>
As a consequence, the actual problem we are dealing with preprocessor -
wise, is to detect whether __VA_ARGS__ expands to an empty token or
not. Knowing when __VA_ARGS__ expands to the empty token is
important as a <b>fundamental operation</b>, because using it in relati=
vely
simple recursive macro expansion constructs, one can come up with the e=
quivalent of
__VA_NARGS__.<br><br>Having a way to detect whether __VA_ARGS__ expands=
to
the "empty" token would thus cover the two seemingly contrast=
ing but completely legal invocations of a VARMACRO_0 - like function - like
macro. The importance of empty argument detection is also analyzed
in a post by Jens Gustedt at <a href=3D"https://gustedt.wordpress.com/2=
010/06/08/detect-empty-macro-arguments/" target=3D"_blank">https://gustedt.=
wordpress.com/2010/06/08/detect-empty-macro-arguments/</a>,
with which I agree to up a point.<br>
<br>
Another clue to why __VA_ARGS__ expanding to the
empty token or not is important, has to do with trailing commas. This l=
ead to GCC implementeing
", ##__VA_ARGS__" as an extension for "eating" the =
trailing comma when
__VA_ARGS__ is empty, while other compilers may use other solutions to =
appeal to the developers requiring it. This leads to a lot of preprocessor =
boilerplate for compiler checking when it happens.<br>
<blockquote type=3D"cite">
<div dir=3D"ltr">Moreover, I never saw it used with any other
arguments than __VA_ARGS__ and I don't think using it with othe=
r
parameters will be useful anyway.<br>
Therefore, instead of having it defined as a function-like
macro, it could be defined as a constant-like macro which would
hold the number of<br>
variadic arguments in the current variadic macro.<br>
<br>
Also, if the idea is juged interesting, it would also be better
to propose __VA_NARGS__ to the C standard committee too. What do
you think of<br>
such a feature?<br>
</div>
-- <br>
=A0 <br>
</blockquote>
I think that a constant identifier in the guise of
__VA_EMPTY__ expanding to a meaningful token for detecting empty - ness
as well as dealing with the need of the ", ##__VA_ARGS__" ext=
ension
would be a better way to deal with the problem as a whole, because it c=
ould be an opportunity to offer something computationally more complete for=
preprocessor metaprogrammers (the work of which made a lot of things possi=
ble when C++11 was not around, just look at boost).<br>
<br>__VA_EMPTY__ 's expansion could be used to construct recursive macr=
o
constructs that "count" arguments by resolving to meaningful
expansions for preprocessor metaprogrammers to use. Since the
preprocessor (when unassisted by metaprogramming implemented in it)
has no way of actually dealing with arithmetic and logical
operations of constant expressions in macro expansions (out of the #if =
directives), we would
have to have a value for __VA_EMPTY__ that is non - numerical.<br>
<br>
I think that this hypothetical __VA_EMPTY__ identifier could thus expan=
d to
an empty token when __VA_ARGS__ is an empty token itself, and to a
comma (i.e. ,) when for all other cases,
for the reasons stated above. Comma expansions and argument concatenati=
ons are among the very essential techniques for preprocessor metaprogrammin=
g after all.<br>
<br>
Thus,=A0 __VA_EMPTY__ in the end could be named as=A0
__VA_COMMA__ and it should be an identifier present in the replacement =
list of a function - like macro provided the ellipsis notation is used in i=
ts parameter definition, just like __VA_ARGS__.<br>
<br>
An inclusive example follows of how such a hypothetical __VA_COMMA__ id=
entifier
could be used in at least two different scenarios, that is in counting
macro arguments and dealing with trailing commas. I cannot stress enoug=
h that this is fictional code since the __VA_COMMA__ identifier does not ex=
ist, so after conceptualizing the abstraction please do report any inconsis=
tencies.<br>
<br>
<pre style=3D"color:rgb(31,28,27);background-color:rgb(255,255,255)"><span =
style=3D"color:rgb(137,136,135)">/**</span>
<span style=3D"color:rgb(137,136,135)"> * </span><b><span style=3D"color:rg=
b(202,146,25);background:none repeat scroll 0% 0% rgb(69,30,26)">WARNING</s=
pan></b><span style=3D"color:rgb(137,136,135)">: fictional C++ code for __V=
A_COMMA__ !</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * The following is a more of a demo=
nstration of a simple way to count macro</span>
<span style=3D"color:rgb(137,136,135)"> * arguments in function - like macr=
os, had a __VA_COMMA__ identifier been</span>
<span style=3D"color:rgb(137,136,135)"> * available for __VA_ARGS__. __VA_C=
OMMA__ is right now a *fictional* constant</span>
<span style=3D"color:rgb(137,136,135)"> * identifier, so do not attempt to =
actually use it!</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * </span><b><span style=3D"color:rg=
b(129,202,45);background:none repeat scroll 0% 0% rgb(247,230,230)">NOTE</s=
pan></b><span style=3D"color:rgb(137,136,135)">: __VA_COMMA__ identifier co=
nvention used in this code.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * The __VA_COMMA__ identifier can b=
e present in the replacement list of a</span>
<span style=3D"color:rgb(137,136,135)"> * function - like macro only if it =
uses the ellipsis notation in its</span>
<span style=3D"color:rgb(137,136,135)"> * parameters. __VA_COMMA__ always e=
xpands to a single comma (,) if and only if</span>
<span style=3D"color:rgb(137,136,135)"> * __VA_ARGS__ does not expand to an=
empty preprocessor token.</span>
<span style=3D"color:rgb(137,136,135)"> *</span>
<span style=3D"color:rgb(137,136,135)"> */</span>
<span style=3D"color:rgb(137,136,135)">/**</span>
<span style=3D"color:rgb(137,136,135)"> * This is far from ideal, but it se=
rves its purpose. Implementing a counter</span>
<span style=3D"color:rgb(137,136,135)"> * macro for 0 to 3 arguments in __V=
A_ARGS__. Notice the use of the fictional</span>
<span style=3D"color:rgb(137,136,135)"> * __VA_COMMA__ object - like macro.=
</span>
<span style=3D"color:rgb(137,136,135)"> */</span>
<span style=3D"color:rgb(7,47,87)">#define VA_NARGS_HELP(...) __VA_COMMA__ =
3, 2, 1, 0,</span>
<span style=3D"color:rgb(7,47,87)">#define VA_NARGS(...) VA_NARGS__(__VA_AR=
GS__ VA_NARGS_HELP())</span>
<span style=3D"color:rgb(7,47,87)">#define VA_NARGS__(...) VA_NARGS_(__VA_A=
RGS__)</span>
<span style=3D"color:rgb(7,47,87)">#define VA_NARGS_(_0, _1, _2, _N, ...) _=
N</span>
<span style=3D"color:rgb(137,136,135)">/**</span>
<span style=3D"color:rgb(137,136,135)"> * We cannot just use (x,...) becaus=
e of C++11 16.3p4. We want to have at</span>
<span style=3D"color:rgb(137,136,135)"> * least another argument passed (su=
ch as an "empty" one), that is mandatory</span>
<span style=3D"color:rgb(137,136,135)"> * for strict C99 preprocessor compl=
iance. A few more lines of preprocessor</span>
<span style=3D"color:rgb(137,136,135)"> * can also implement a no - op for =
when LOGGER() is invoked (perfectly</span>
<span style=3D"color:rgb(137,136,135)"> * legal C++11, C99). Notice that __=
VA_COMMA__ expands to , if and only if</span>
<span style=3D"color:rgb(137,136,135)"> * __VA_ARGS__ is not empty. The exa=
mple is inspired by Wikipedia's entry</span>
<span style=3D"color:rgb(137,136,135)"> * on <a href=3D"http://en.wikipedia=
..org/wiki/Variadic_macro">http://en.wikipedia.org/wiki/Variadic_macro</a> f=
or the , ##__VA_ARGS__</span>
<span style=3D"color:rgb(137,136,135)"> * GCC extension, but made consisten=
t with 16.3p4.</span>
<span style=3D"color:rgb(137,136,135)"> */</span>
<span style=3D"color:rgb(7,47,87)">#define LOGGER(...) LOGGER_B(LOGGER_, VA=
_NARGS(__VA_COMMA__))(__VA_ARGS__)</span>
<span style=3D"color:rgb(7,47,87)">#define LOGGER_B(a,b) LOGGER_C(a, b)</sp=
an>
<span style=3D"color:rgb(7,47,87)">#define LOGGER_C(a,b,...) a ## b</span>
<span style=3D"color:rgb(137,136,135)">/**</span>
<span style=3D"color:rgb(137,136,135)"> * Our use of the VA_NARGS(__VA_COMM=
A__) means that if __VA_ARGS__ is not</span>
<span style=3D"color:rgb(137,136,135)"> * the empty token, then because of =
__VA_COMMA__ it will expand to 2. The</span>
<span style=3D"color:rgb(137,136,135)"> * alternative, where __VA_ARGS__ is=
null, would expand it to 0, as above.</span>
<span style=3D"color:rgb(137,136,135)"> * Thus, we need two different macro=
s, one that works with a single argument,</span>
<span style=3D"color:rgb(137,136,135)"> * and one working with at least one=
argument, because of the way the ellipsis</span>
<span style=3D"color:rgb(137,136,135)"> * is forcing us to do function - li=
ke macro invocation in C++11 and C99.</span>
<span style=3D"color:rgb(137,136,135)"> */</span>
<span style=3D"color:rgb(7,47,87)">#define LOGGER_2(fliteral, ...) \</span>
<span style=3D"color:rgb(7,47,87)"> fprintf(stderr, "%s(%d): "=
fliteral "\n",__FILE__,__LINE__,__VA_ARGS__)</span>
<span style=3D"color:rgb(137,136,135)">/**</span>
<span style=3D"color:rgb(137,136,135)"> * Here, __VA_ARGS__ actually always=
expands to a single argument, which</span>
<span style=3D"color:rgb(137,136,135)"> * is analogous to fliteral because =
of how __VA_COMMA__ makes VA_NARGS expand!</span>
<span style=3D"color:rgb(137,136,135)"> */</span>
<span style=3D"color:rgb(7,47,87)">#define LOGGER_0(...) \</span>
<span style=3D"color:rgb(7,47,87)"> fprintf(stderr, "%s(%d): "=
__VA_ARGS__ "\n", __FILE__,__LINE__)</span>
VA_NARGS() <span style=3D"color:rgb(137,136,135)">// 0 : __VA_ARG=
S__ is empty, thus __VA_COMMA__ is empty</span>
VA_NARGS(a) <span style=3D"color:rgb(137,136,135)">// 1 : __VA_ARG=
S__ is NOT empty, thus __VA_COMMA__ is ,</span>
VA_NARGS(a,b) <span style=3D"color:rgb(137,136,135)">// 2 : __VA_ARG=
S__ is NOT empty, thus __VA_COMMA__ is ,</span>
VA_NARGS(a,b,c) <span style=3D"color:rgb(137,136,135)">// 3 : __VA_ARG=
S__ is NOT empty, thus __VA_COMMA__ is ,</span>
VA_NARGS(,) <span style=3D"color:rgb(137,136,135)">// 2 : __VA_ARG=
S__ is NOT empty, thus __VA_COMMA__ is ,</span>
<span style=3D"color:rgb(137,136,135)">// and right=
now it consists of 2 empty tokens!</span>
LOGGER(<span style=3D"color:rgb(191,3,3)">"too many balloons %d"<=
/span>, <span style=3D"color:rgb(176,128,0)">42</span>) <span style=3D"colo=
r:rgb(137,136,135)">// OK! __VA_COMMA__ leads to LOGGER_2</span>
LOGGER(<span style=3D"color:rgb(191,3,3)">"just enough to go by"<=
/span>) <span style=3D"color:rgb(137,136,135)">// OK! __VA_COMMA__ lead=
s to LOGGER_0</span>
</pre>
Implementing __VA_COMMA__ would be trivial and it could also be used in=
far more advanced constructs as
a fundamental building block for computation, just like the use of
commas in preprocessor metaprogramming libraries like in boost preproce=
ssor by Vesa Karvonen and Paul Mensonides and Jens Gustedt's P99.<br><b=
r>Given the fact that no
arithmetical and logical operations are required to deduce the
meaning of the expansion within the preprocessor and it being
versatile enough to be deployed in different scenarios, I think that
we should consider a __VA_COMMA__ identifier as a better option to just=
__VA_NARGS__ since it seems to be computationally superior.<br><br>I am no=
t arguing about whether __VA_NARGS__ alone could be used in order to deal w=
ith the problems I have stated above (not without more complicated construc=
ts!), I am saying that I just do not believe that __VA_NARGS__ is as import=
ant given that it becomes trivial when __VA_COMMA__ like the one demonstrat=
ed above is available.<br>
<br>
That of course, is just an opinion on a fictional concept and nothing m=
ore.<br>
<br>
</div>
</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--bcaec5430bcac7209904e9bbfd68--
.
Author: Jeremiah Willcock <jewillco@crest.iu.edu>
Date: Sun, 27 Oct 2013 13:24:52 -0400
Raw View
On Oct 27, 2013, at 1:05 PM, George Makrydakis <irrequietus@gmail.com> wrot=
e:
> On 10/25/2013 09:36 PM, morwenn29@gmail.com wrote:
>> The C++11 preprocessor inherited variadic macros from the C99 preprocess=
or. When variadic macros are used, the user often wants to know
>> the exact number of variadic arguments that have been given to the macro=
.. The common trick to get the number of arguments is to use a macro,
>> usually named VA_NARGS or VA_NUM_ARGS which is defined as follows:
>>=20
>> #define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...)
>> N
>>=20
>> #define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
> That macro and its kin are well known to be incomplete for several reason=
s, while also not easily extensible. There are much better ways to do this =
and people familiar with C99 preprocessor metaprogramming are quite aware o=
f how to implement and use such constructs even to extremes that go beyond=
the purpose of this post. For the sake of record, the technique you are re=
ferring to relies on variations of Laurent Deniau's PP_NARG in https://grou=
ps.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s, although other authors =
have done similar things in the past.
>> With this macro, the user can use get the numbers of arguments of a macr=
o with VA_NARGS(__VA_ARGS__).
>>=20
>> However, the number of arguments is limited (maximum of 63 arguments) an=
d it does not work correctly if zero arguments are given.
>> Therefore, it might be great to require implementations to provide a mac=
ro __VA_NARGS__ which resolves these two problems.
> There is more to this than actually discussed here but let's focus on the=
simple aspect of counting macro arguments. Strictly speaking, there is no =
such thing as "zero" arguments in function - like macro expansion, because =
when "no arguments" are passed to a function - like macro whose parameters =
in definition consist only of the ellipsis notation, they are collectively =
treated as a single empty preprocessor token which itself is a single argum=
ent!
(snip)
> I am not arguing about whether __VA_NARGS__ alone could be used in order =
to deal with the problems I have stated above (not without more complicated=
constructs!), I am saying that I just do not believe that __VA_NARGS__ is =
as important given that it becomes trivial when __VA_COMMA__ like the one d=
emonstrated above is available.
>=20
> That of course, is just an opinion on a fictional concept and nothing mor=
e.
Wouldn=92t it be important to have both? __VA_NARGS__ can be used for othe=
r things than just testing whether there are zero or more arguments. The a=
lternative you give still only works for up to a fixed number of arguments.=
__VA_COMMA__ would be nice as well. Actually, it might be worthwhile to =
consider more general updates to the preprocessor to replace the kinds of =
=93tricks=94 used in Boost.Preprocessor (and the need for that library).
=97 Jeremiah Willcock
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Sun, 27 Oct 2013 10:54:40 -0700 (PDT)
Raw View
------=_Part_247_1925275.1382896480340
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
Le dimanche 27 octobre 2013 18:24:52 UTC+1, Jeremiah Willcock a =E9crit :
>
> Actually, it might be worthwhile to consider more general updates to the=
=20
> preprocessor to replace the kinds of =93tricks=94 used in Boost.Preproces=
sor=20
> (and the need for that library).
>
> If the problem that preprocessor solutions want to solve is deemed=20
important enough to be solved in a standard way, my bet is that the=20
committee will want to fix it in a way which doesn't need the=20
preprocessor. I doubt that the committee will want to do more than=20
Incorporating changes from C.
Yours,
--=20
Jean-Marc
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_247_1925275.1382896480340
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Le dimanche 27 octobre 2013 18:24:52 UTC+1, Jeremiah Willc=
ock a =E9crit :<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Actually, =
it might be worthwhile to consider more general updates to the preprocessor=
to replace the kinds of =93tricks=94 used in Boost.Preprocessor (and the n=
eed for that library).<br>
<br></blockquote><div>If the problem that preprocessor solutions want to so=
lve is deemed important enough to be solved in a standard way, my bet is th=
at the committee will want to fix it in a way which doesn't need the prepro=
cessor. I doubt that the committee will want to do more than Incorpor=
ating changes from C.<br><br>Yours,<br><br>-- <br>Jean-Marc<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_247_1925275.1382896480340--
.
Author: George Makrydakis <irrequietus@gmail.com>
Date: Sun, 27 Oct 2013 14:50:38 -0700 (PDT)
Raw View
------=_Part_281_20984433.1382910638582
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
On Sunday, October 27, 2013 7:24:52 PM UTC+2, Jeremiah Willcock wrote:
>
> On Oct 27, 2013, at 1:05 PM, George Makrydakis <irreq...@gmail.com<javasc=
ript:>>=20
> wrote:=20
>
> [ ... ]=20
>
> Wouldn=92t it be important to have both? __VA_NARGS__ can be used for ot=
her=20
> things than just testing whether there are zero or more arguments. The=
=20
> alternative you give still only works for up to a fixed number of=20
> arguments. __VA_COMMA__ would be nice as well. Actually, it might be=20
> worthwhile to consider more general updates to the preprocessor to replac=
e=20
> the kinds of =93tricks=94 used in Boost.Preprocessor (and the need for th=
at=20
> library).=20
>
> =97 Jeremiah Willcock
=20
Thanks for your comment. Of course one could have both, the question is=20
which one is computationally more important. One could argue in the same=20
manner over implementing all the logic gates using nand over nor. =20
__VA_NARGS__ would eventually bring about faster the question of whether=20
constant expressions and which constant expressions should be evaluated=20
within the preprocessor for the preprocessor's sake. As it is, __VA_NARGS__=
=20
resolves to a "number", that is in a preprocessor token that has a variable=
=20
expansion result depending on length which can limit its use. __VA_COMMA__=
=20
is a simpler alternative with an always known a priori expansion result and=
=20
constructing recursive macro expansion constructs for really great=20
recursion lengths in few lines of code is far from being a=20
disproportionately tenuous exercise.
Do remember that people who have need for such facilities are usually=20
people who go beyond plain substitution, into the realm of code generation.=
=20
Therefore it is not beyond their reach to implement such things. That is=20
why I think that a __VA_COMMA__ identifier as described above would be a=20
better choice.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_281_20984433.1382910638582
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, October 27, 2013 7:24:52 PM UTC+2, Jere=
miah Willcock wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Oct 27,=
2013, at 1:05 PM, George Makrydakis <<a href=3D"javascript:" target=3D"=
_blank" gdf-obfuscated-mailto=3D"W8AsuHU86lYJ">irreq...@gmail.com</a>> w=
rote:
<br>
<br></blockquote><div>[ ... ] <br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;">
<br>Wouldn=92t it be important to have both? __VA_NARGS__ can be used=
for other things than just testing whether there are zero or more argument=
s. The alternative you give still only works for up to a fixed number=
of arguments. __VA_COMMA__ would be nice as well. Actually, it=
might be worthwhile to consider more general updates to the preprocessor t=
o replace the kinds of =93tricks=94 used in Boost.Preprocessor (and the nee=
d for that library).
<br>
<br>=97 Jeremiah Willcock</blockquote><div> <br>Thanks for your commen=
t. Of course one could have both, the question is which one is computationa=
lly more important. One could argue in the same manner over implementing al=
l the logic gates using nand over nor. __VA_NARGS__ would eventually =
bring about faster the question of whether constant expressions and which c=
onstant expressions should be evaluated within the preprocessor for the pre=
processor's sake. As it is, __VA_NARGS__ resolves to a "number", that is in=
a preprocessor token that has a variable expansion result depending on len=
gth which can limit its use. __VA_COMMA__ is a simpler alternative with an =
always known a priori expansion result and constructing recursive macro exp=
ansion constructs for really great recursion lengths in few lines of code i=
s far from being a disproportionately tenuous exercise.<br><br>Do remember =
that people who have need for such facilities are usually people who go bey=
ond plain substitution, into the realm of code generation. Therefore it is =
not beyond their reach to implement such things. That is why I think that a=
__VA_COMMA__ identifier as described above would be a better choice.<br><b=
r><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_281_20984433.1382910638582--
.
Author: George Makrydakis <irrequietus@gmail.com>
Date: Sun, 27 Oct 2013 15:27:31 -0700 (PDT)
Raw View
------=_Part_405_31510570.1382912851868
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
On Sunday, October 27, 2013 7:54:40 PM UTC+2, Jean-Marc Bourguet wrote:
>
> Le dimanche 27 octobre 2013 18:24:52 UTC+1, Jeremiah Willcock a =E9crit :
>>
>> Actually, it might be worthwhile to consider more general updates to the=
=20
>> preprocessor to replace the kinds of =93tricks=94 used in Boost.Preproce=
ssor=20
>> (and the need for that library).
>>
>> If the problem that preprocessor solutions want to solve is deemed=20
> important enough to be solved in a standard way, my bet is that the=20
> committee will want to fix it in a way which doesn't need the=20
> preprocessor. I doubt that the committee will want to do more than=20
> Incorporating changes from C.
>
>
Some, if not all, of the problems that preprocessor solutions were deployed=
=20
for in libraries like boost for example, were detrimental to implementing a=
=20
variety of constructs that aided us in exploring things like the uses of=20
"variadic" templates in C++03 (for which we all have our share of memories=
=20
and tricks for before the C++11 era) and other constructs where code=20
generation was required.
Preprocessor macros can be very important as code generation tools, but the=
=20
limited features the current C and C++ preprocessor implementations offer=
=20
do not allow easy exploration of this area without resorting to uncanny=20
ways of doing metaprogramming with the preprocessor itself. After all, the=
=20
C preprocessor was primarily conceived as a text subtitution tool on this=
=20
area. It does not come as a surprise that most of the preprocessor based=20
code generating constructs (i.e. not plain substution oriented ones) have a=
=20
very steep learning curve for people implementing them.
If we had a lisp - like preprocessor for code generation in C / C++, there=
=20
would be several ways we would be using it to reduce code boilerplate=20
required for a variety of situations. At times, you do need to methodicaly=
=20
generate text for rather repetitive and condescending building block=20
boilerplate for template metaprograms that tend to rightfully bully over=20
the majority of average use examples. A lot of boost internals are=20
testament to such an approach and experimentation.
Eventually, the preprocessor of our beloved C and C++ could evolve into=20
something more friendly to code generation instead of remaining in its=20
humble roots of plain text substitution. Until that is forcibly thrown upon=
=20
it by the then modern times and necessities, I think that minor adjustments=
=20
to its modus operandi could yield a lot of benefits in code generation. I=
=20
see no harm in proposing things like __VA_NARGS__ or __VA_COMMA__ if they=
=20
are conceived as steps towards that direction, regardless of their seeming=
=20
clumsiness.
=20
> Yours,
>
> --=20
> Jean-Marc
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_405_31510570.1382912851868
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, October 27, 2013 7:54:40 PM UTC+2, Jean=
-Marc Bourguet wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">Le dimanche 27 octobre 2013 18:24:52 UTC+1, Jeremiah Willcock a =
=E9crit :<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex">Actually, it might be=
worthwhile to consider more general updates to the preprocessor to replace=
the kinds of =93tricks=94 used in Boost.Preprocessor (and the need for tha=
t library).<br>
<br></blockquote><div>If the problem that preprocessor solutions want to so=
lve is deemed important enough to be solved in a standard way, my bet is th=
at the committee will want to fix it in a way which doesn't need the prepro=
cessor. I doubt that the committee will want to do more than Incorpor=
ating changes from C.<br><br></div></div></blockquote><div><br>Some, if not=
all, of the problems that preprocessor solutions were deployed for in libr=
aries like boost for example, were detrimental to implementing a variety of=
constructs that aided us in exploring things like the uses of "variadic" t=
emplates in C++03 (for which we all have our share of memories and tricks f=
or before the C++11 era) and other constructs where code generation was req=
uired.<br><br>Preprocessor macros can be very important as code generation =
tools, but the limited features the current C and C++ preprocessor implemen=
tations offer do not allow easy exploration of this area without resorting =
to uncanny ways of doing metaprogramming with the preprocessor itself. Afte=
r all, the C preprocessor was primarily conceived as a text subtitution too=
l on this area. It does not come as a surprise that most of the preprocesso=
r based code generating constructs (i.e. not plain substution oriented ones=
) have a very steep learning curve for people implementing them.<br><br>If =
we had a lisp - like preprocessor for code generation in C / C++, there wou=
ld be several ways we would be using it to reduce code boilerplate required=
for a variety of situations. At times, you do need to methodicaly generate=
text for rather repetitive and condescending building block boilerplate fo=
r template metaprograms that tend to rightfully bully over the majority of =
average use examples. A lot of boost internals are testament to such an app=
roach and experimentation.<br><br>Eventually, the preprocessor of our belov=
ed C and C++ could evolve into something more friendly to code generation i=
nstead of remaining in its humble roots of plain text substitution. Until t=
hat is forcibly thrown upon it by the then modern times and necessities, I =
think that minor adjustments to its modus operandi could yield a lot of ben=
efits in code generation. I see no harm in proposing things like __VA_NARGS=
__ or __VA_COMMA__ if they are conceived as steps towards that direction, r=
egardless of their seeming clumsiness.<br> </div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div>Yours,<br><br>-- <br>Jean-Mar=
c<br></div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_405_31510570.1382912851868--
.
Author: morwenn29@gmail.com
Date: Mon, 28 Oct 2013 04:08:37 -0700 (PDT)
Raw View
------=_Part_102_6710708.1382958517608
Content-Type: text/plain; charset=ISO-8859-1
At first, I only proposed __VA_NARGS__ in order to standardize something
that has already been written by dozens of programmers and which still
often has some problems.
My aim wasn't to propose a change that fundamental and that important, but
of course, __VA_COMMA__ would be a nice and powerful feature, offering much
more to
preprocessor programmers than what they already have.
Having both would be somehow great, and improving code generation would be
kind of awesome :)
I think George's big post could be turned into a proper paper: it's
motivating enough!
But, it would be post to present it to the C standard first, and it could
be separated into two papers (__VA_NARGS__ and __VA_COMMA__); that way,
having one of the
ideas rejecting wouldn't automatically mean having the other rejected.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_102_6710708.1382958517608
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">At first, I only proposed __VA_NARGS__ in order to standar=
dize something that has already been written by dozens of programmers and w=
hich still often has some problems.<br>My aim wasn't to propose a change th=
at fundamental and that important, but of course, __VA_COMMA__ would be a n=
ice and powerful feature, offering much more to<br>preprocessor programmers=
than what they already have.<br>Having both would be somehow great, and im=
proving code generation would be kind of awesome :)<br><br>I think George's=
big post could be turned into a proper paper: it's motivating enough!<br>B=
ut, it would be post to present it to the C standard first, and it could be=
separated into two papers (__VA_NARGS__ and __VA_COMMA__); that way, havin=
g one of the<br>ideas rejecting wouldn't automatically mean having the othe=
r rejected.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_102_6710708.1382958517608--
.
Author: George Makrydakis <irrequietus@gmail.com>
Date: Mon, 28 Oct 2013 21:09:21 +0200
Raw View
--047d7b67888069529204e9d1d6a5
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Mon, Oct 28, 2013 at 1:08 PM, <morwenn29@gmail.com> wrote:
> At first, I only proposed __VA_NARGS__ in order to standardize something
> that has already been written by dozens of programmers and which still
> often has some problems.
> My aim wasn't to propose a change that fundamental and that important, bu=
t
> of course, __VA_COMMA__ would be a nice and powerful feature, offering mu=
ch
> more to
> preprocessor programmers than what they already have.
> Having both would be somehow great, and improving code generation would b=
e
> kind of awesome :)
>
I agree with you conceptually.
I think that adding either or both of said identifiers for macros using the
ellipsis notation in their definition is at some point inevitable since it
would ease the preprocessor's transition to a more code - generating
friendly tool other than a plain text substitution workaround. The problem
however is not only which between the two allows an implementation of the
other, but also which between the two is the unambiguous one. This requires
some very meticulous reading of the standards involved. After reviewing the
matter I exposed in my initial post to this thread, I think we have reason
to believe that there are some problems with ambiguity that need to be
dealt with.
>
> I think George's big post could be turned into a proper paper: it's
> motivating enough!
>
Thanks for your heads up and enthousiasm, I really appreciate it!
> But, it would be post to present it to the C standard first, and it could
> be separated into two papers (__VA_NARGS__ and __VA_COMMA__); that way,
> having one of the
> ideas rejecting wouldn't automatically mean having the other rejected.
>
I think that more work should be done before presenting either of these
elsewhere to be honest and I am not convinced right now that they should be
made separate. I took the liberty of writing up another piece of code where
I try to study the behaviour of both and whether or not these two are
equivalent for building up various simple constructs to use with the
preprocessor.
In summary, __VA_NARGS__ and __VA_COMMA__ could be made "equivalent" for
what concerns deploying them in preprocessor constructs for detecting the
"empty" token (and even getting rid of the need for extensions like the ,
##__VA_ARGS__ one). This "equivalence" stems from both expanding to non -
empty tokens that cannot be used as identifiers by preprocessor macros and
therefore cannot trigger other macros arbitrarily when used within complex
preprocessor constructs.
The problem however lies in the uniqueness of the token either of these
builtin identifiers resolve to. C99 =A76.10.3p4 and C++11 =A716.3p4 intepre=
t
the empty token as a single token, thus *NOT* allowing an eventual
__VA_NARGS__ to expand to 0 (zero) when it is the single argument used in
the replacement list for the ellipsis notation. Since the empty token, is a
token, then __VA_NARGS__ would have no escape but to resolve to 1. That
would be ambiguous with a single non - empty argument being passed for code
flows past the preprocessor.
This is also illustrated in the case of a variadic macro invoked with ()
thus having __VA_NARGS__ expand to 0 but a macro with (,) - that is two
empty tokens - to 2, because that is the semantic intention of the comma. I
would find such a compromise difficult to approach because of its ambiguity
and "special treatment" status. __VA_COMMA__ on the other hand, it not
being a "digits" - token would allow the end user to interpret () and (,)
in a way compatible with his / her own programming flow when implementing a
beyond - naive recursive counter for the arguments easily, because of
__VA_COMMA__ being available. As such, __VA_COMMA__ would allow us to
continue to intepret the empty token the way it is intepreted by both
standards for such a long time.
Together with the fact that it deals away with the need for a (,
##__VA_ARGS__) extension, it would be a harmless, useful and unambiguous
addition. The following example is valid C++11 (and C99 of course !) and it
is full of comments detailing what I am studied on the matter. It is kind
of a long read... but I think it kind of helps the conceptual point I am
trying to make. There are several other details I have been thinking about,
but for the time being this is more than enough. Comments are very welcome.
[segment begins]
#include <cstdio>
/** * Please compile with -Werror -Wall -Wextra -std=3Dc++11 -pedantic
(very strict!) * * A check for the empty preprocessor token in C++11.
Notice the implementation * of MACRO_EMPTY(...). This is valid code
for demonstrational purposes. * * In said macro, __VA_ARGS__ could be
substituted by either of the eventual * __VA_NARGS__ or __VA_COMMA__
identifiers. Either of said identifiers could * exist in the
replacement list of a function - like macro that uses the * ellipsis
notation in its definition. While __VA_COMMA__ expands to a single *
comma if and only if __VA_ARGS__ does not expand to the empty token,
the * __VA_NARGS__ would expand to a token consisting only of decimal
digits and * representing the number of comma separated tokens to
which __VA_ARGS__ * expands to. * *
---------------------------------------------------------------------------=
-
* The macro that would be best served by either of these is
MACRO_EMPTY(...) * and thus its writing would be greately simplified :
* * (a) using __VA_NARGS__ : * * #define MACRO_EMPTY(...) \ *
MACRO_EMPTY_1(MACRO_EMPTY_0 __VA_NARGS__ ()) * * (b) using
__VA_COMMA__ : * * #define MACRO_EMPTY(...) \ *
MACRO_EMPTY_1(MACRO_EMPTY_0 __VA_COMMA__ ()) * *
---------------------------------------------------------------------------=
-
* * (1) "Last token is a function macro in __VA_ARGS__" is an issue
both * identifiers (__VA_NARGS__ and __VA_COMMA__) deal with
reducing the amount * of constructs necessary when checking for
the empty preprocessor token. * * Notice that if the last token in
__VA_ARGS__ is a defined function macro, * the balanced parenthesis
token following it would result in invoking said * macro, therefore
providing unexpected results. Current ways of bypassing * this
particular problem are available requiring greater complexity in * the
preprocessor constructs involved but are not presented here because
they * are out of the purpose of this demonstration. * * (2) "First
token is a balanced parenthesis in __VA_ARGS__" is an issue both *
identifiers (__VA_NARGS__ and __VA_COMMA__) deal with reducing the
amount * of constructs necessary when checking for the empty
preprocessor token. * * (3) __VA_NARGS__ and __VA_COMMA__ are
equivalent for their primary purposes * but both require additional
preprocessor metaprogramming constructs when * used for detecting
__VA_ARGS__ expansion to the empty preprocessor token. * * If the
hypothetical __VA_NARGS__ identifier was used, it would yield a token
* starting with a digit, thus invocation of MACRO_EMPTY_0 would not
occur. The * same holds for the hypothetical __VA_COMMA__. Both
expansions of said * identifiers yield tokens that could have not been
used as identifiers * themselves (that is in #define statements) thus
resolving the "last token * is a function macro in __VA_ARGS__" issue
as presented in (1). * * (4) __VA_COMMA__ by definition expands only
to a single comma if and only if * __VA_ARGS__ does not expand to
the empty token which means that it has * unambiguous meaning over
__VA_NARGS__ when it comes to handling said * token, due to the
definition of the "no arguments" token in C99 =A76.10.3p4 * and
C++11 =A716.3p4. Thus, the notational advantage of __VA_NARGS__ in *
providing argument count * * This means that __VA_NARGS__ can have
different meanings for code constructs * out of the realm of the
preprocessor when it comes to assuming the value * "1" for both a
single token (no commas) and the empty token. __VA_COMMA__ *
expansion *is* the empty token unambiguously if and only if
__VA_ARGS__ is, * in all other cases it expands to a comma. * * (5)
__VA_COMMA__ takes away the need for a (, ##__VA_ARGS__) extension
with * no additional constructs required, while __VA_NARGS__
requires them in * order to do so but may be ambiguous because of
(4). * * __VA__COMMA__ __VA_ARGS__ : a comma precedes
__VA_ARGS__ if and only if *
__VA_ARGS__ does not expand to the empty *
preprocessor token. * * X(__VA_NARGS__) __VA_ARGS__: X would
have to be a macro that would *
expand to a comma if __VA_NARGS__ was 0, *
but because of (4) such a macro may be *
unfeasible to implement if __VA_NARGS__ *
has to resolve to the minimum of "1". * */
#define MACRO_0 0#define MACRO_1 1,#define MACRO_EMPTY_0() 1,#define
MACRO_MACRO_EMPTY_0 0,#define MACRO_EMPTY_1(...)
MACRO_EMPTY_2(__VA_ARGS__)#define MACRO_EMPTY_2(...)
MACRO_EMPTY_3(MACRO_ ## __VA_ARGS__)#define MACRO_EMPTY_3(...)
MACRO_EMPTY_4(__VA_ARGS__)#define MACRO_EMPTY_4(x,...) x#define
MACRO_EMPTY_5() 0,#define MACRO_MACRO_EMPTY_5 1,#define
MACRO_EMPTY_6(x,y) MACRO_EMPTY_7(x,y)#define MACRO_EMPTY_7(x,y)
MACRO_EMPTY_##x##y()
/* This is an implementation of the AND logic gate */
#define MACRO_EMPTY_00() 0#define MACRO_EMPTY_10() 0#define
MACRO_EMPTY_11() 1#define MACRO_EMPTY_01() 0
/** * The actual macro for checking for the "empty" token provided (1)
does not * apply, because (1) would require a more complicated version
and of course * is what __VA_NARGS__ / __VA_COMMA__ would deal with
best, making a lot of * the macros defined above pointless. */#define
MACRO_EMPTY(...) \ MACRO_EMPTY_6( MACRO_EMPTY_1(MACRO_EMPTY_0
__VA_ARGS__ ()) \ , MACRO_EMPTY_1(MACRO_EMPTY_5
__VA_ARGS__,) )
/** * Using string concatenation for implementing an expression
evaluation of * sorts, preprocessor - wise. Combining the following
with a recursion and * an addition construct can yield the number of
tokens in a comma separated * list of preprocessor tokens. This means
that at a cost, __VA_NARGS__ could * be implemented as VA_NARGS(...)
using preprocessor metaprogramming. The * techniques involved for this
vary, but outside naive implementations require * few lines for
several hundred (and more) tokens to be accounted for. */#define
MACRO_IFELSE(x,y,z) MACRO_IFELSE_(x,y,z)#define MACRO_IFELSE_(x,y,z)
MACRO_IFELSE##x(y,z)#define MACRO_IFELSE1(y,z) y#define
MACRO_IFELSE0(y,z) z
int main() {
// full !
printf("%s\n" , MACRO_IFELSE(MACRO_EMPTY(a),"null","full"));
printf("%s\n" , MACRO_IFELSE(MACRO_EMPTY(a,b),"null","full"));
printf("%s\n" , MACRO_IFELSE(MACRO_EMPTY(,),"null","full"));
printf("%s\n" , MACRO_IFELSE(MACRO_EMPTY(()),"null","full"));
printf("%s\n" , MACRO_IFELSE(MACRO_EMPTY(+),"null","full"));
printf("%s\n" , MACRO_IFELSE(MACRO_EMPTY([]),"null","full"));
printf("%s\n\n", MACRO_IFELSE(MACRO_EMPTY(!),"null","full"));
// null, i.e. the empty token, which is actually "argument count 1" for=
what
// the preprocessor is concerned but that not may always be for what th=
e
// end user is concerned. __VA_COMMA__ has an advantage over such an
// occasion as well since it would allow the end user to take that
// decision for his / her own needs.
printf("%s\n", MACRO_IFELSE(MACRO_EMPTY(/**/),"null","full"));
printf("%s\n", MACRO_IFELSE(MACRO_EMPTY(),"null","full"));
*return* {};
}
[segment ends]
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--047d7b67888069529204e9d1d6a5
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Mon, Oct 28, 2013 at 1:08 PM, <span dir=3D"ltr"><<a=
href=3D"mailto:morwenn29@gmail.com" target=3D"_blank">morwenn29@gmail.com<=
/a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quo=
te"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">At first, I only proposed __VA_NARGS__ in order to standar=
dize something that has already been written by dozens of programmers and w=
hich still often has some problems.<br>My aim wasn't to propose a chang=
e that fundamental and that important, but of course, __VA_COMMA__ would be=
a nice and powerful feature, offering much more to<br>
preprocessor programmers than what they already have.<br>Having both would =
be somehow great, and improving code generation would be kind of awesome :)=
<br></div></blockquote><div><br>I agree with you conceptually.<br><br>I thi=
nk that adding either or both of said identifiers for macros using the elli=
psis notation in their definition is at some point inevitable since it woul=
d ease the preprocessor's transition to a more code - generating friend=
ly tool other than a plain text substitution workaround. The problem howeve=
r is not only which between the two allows an implementation of the other, =
but also which between the two is the unambiguous one. This requires some v=
ery meticulous reading of the standards involved. After reviewing the matte=
r I exposed in my initial post to this thread, I think we have reason to be=
lieve that there are some problems with ambiguity that need to be dealt wit=
h.<br>
</div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div =
dir=3D"ltr"><br>I think George's big post could be turned into a proper=
paper: it's motivating enough!<br>
</div></blockquote><div><br>Thanks for your heads up and enthousiasm, I rea=
lly appreciate it!<br>=A0<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex">
<div dir=3D"ltr">But, it would be post to present it to the C standard firs=
t, and it could be separated into two papers (__VA_NARGS__ and __VA_COMMA__=
); that way, having one of the<br>ideas rejecting wouldn't automaticall=
y mean having the other rejected.<br>
</div></blockquote><div><br></div><div>I think that more work should be don=
e before presenting either of these elsewhere to be honest and I am not con=
vinced right now that they should be made separate. I took the liberty of w=
riting up another piece of code where I try to study the behaviour of both =
and whether or not these two are equivalent for building up various simple =
constructs to use with the preprocessor.<br>
<br></div><div>In summary, __VA_NARGS__ and __VA_COMMA__ could be made &quo=
t;equivalent" for what concerns deploying them in preprocessor constru=
cts for detecting the "empty" token (and even getting rid of the =
need for extensions like the , ##__VA_ARGS__ one). This "equivalence&q=
uot; stems from both expanding to non - empty tokens that cannot be used as=
identifiers by preprocessor macros and therefore cannot trigger other macr=
os arbitrarily when used within complex preprocessor constructs.<br>
<br>The problem however lies in the uniqueness of the token either of these=
builtin identifiers resolve to. C99 =A76.10.3p4 and C++11 =A716.3p4 intepr=
et the empty token as a single token, thus <b>NOT</b> allowing an eventual =
__VA_NARGS__ to expand to 0 (zero) when it is the single argument used in t=
he replacement list for the ellipsis notation. Since the empty token, is a =
token, then __VA_NARGS__ would have no escape but to resolve to 1. That wou=
ld be ambiguous with a single non - empty argument being passed for code fl=
ows past the preprocessor.<br>
<br>This is also illustrated in the case of a variadic macro invoked with (=
) thus having __VA_NARGS__ expand to 0 but a macro with (,) - that is two e=
mpty tokens - to 2, because that is the semantic intention of the comma. I =
would find such a compromise difficult to approach because of its ambiguity=
and "special treatment" status. __VA_COMMA__ on the other hand, =
it not being a "digits" - token would allow the end user to inter=
pret () and (,) in a way compatible with his / her own programming flow whe=
n implementing a beyond - naive recursive counter for the arguments easily,=
because of __VA_COMMA__ being available. As such, __VA_COMMA__ would allow=
us to continue to intepret the empty token the way it is intepreted by bot=
h standards for such a long time.<br>
<br>Together with the fact that it deals away with the need for a (, ##__VA=
_ARGS__) extension, it would be a harmless, useful and unambiguous addition=
.. The following example is valid C++11 (and C99 of course !) and it is full=
of comments=20
detailing what I am studied on the matter. It is kind of a long read... but=
I think it kind of helps the conceptual point I am trying to make. There a=
re several other details I have been thinking about, but for the time being=
this is more than enough. Comments are very welcome.<br>
<br></div><div>[segment begins]<br></div><div><pre style=3D"color:rgb(31,28=
,27);background-color:rgb(255,255,255)"><span style=3D"color:rgb(7,47,87)">=
#include </span><span style=3D"color:rgb(7,47,87)"><cstdio></span>
<span style=3D"color:rgb(137,136,135)">/**</span>
<span style=3D"color:rgb(137,136,135)"> * Please compile with -Werror -Wall=
-Wextra -std=3Dc++11 -pedantic (very strict!)</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * A check for the empty preprocesso=
r token in C++11. Notice the implementation</span>
<span style=3D"color:rgb(137,136,135)"> * of MACRO_EMPTY(...). This is vali=
d code for demonstrational purposes.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * In said macro, __VA_ARGS__ could =
be substituted by either of the eventual</span>
<span style=3D"color:rgb(137,136,135)"> * __VA_NARGS__ or __VA_COMMA__ iden=
tifiers. Either of said identifiers could</span>
<span style=3D"color:rgb(137,136,135)"> * exist in the replacement list of =
a function - like macro that uses the</span>
<span style=3D"color:rgb(137,136,135)"> * ellipsis notation in its definiti=
on. While __VA_COMMA__ expands to a single</span>
<span style=3D"color:rgb(137,136,135)"> * comma if and only if __VA_ARGS__ =
does not expand to the empty token, the</span>
<span style=3D"color:rgb(137,136,135)"> * __VA_NARGS__ would expand to a to=
ken consisting only of decimal digits and</span>
<span style=3D"color:rgb(137,136,135)"> * representing the number of comma =
separated tokens to which __VA_ARGS__</span>
<span style=3D"color:rgb(137,136,135)"> * expands to.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * ---------------------------------=
-------------------------------------------</span>
<span style=3D"color:rgb(137,136,135)"> * The macro that would be best serv=
ed by either of these is MACRO_EMPTY(...)</span>
<span style=3D"color:rgb(137,136,135)"> * and thus its writing would be gre=
ately simplified :</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * (a) using __VA_NARGS__ :</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * #define MACRO_EMPTY(...) \</=
span>
<span style=3D"color:rgb(137,136,135)"> * MACRO_EMPTY_1(MACRO_=
EMPTY_0 __VA_NARGS__ ())</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * (b) using __VA_COMMA__ :</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * #define MACRO_EMPTY(...) \</=
span>
<span style=3D"color:rgb(137,136,135)"> * MACRO_EMPTY_1(MACRO_=
EMPTY_0 __VA_COMMA__ ())</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * ---------------------------------=
-------------------------------------------</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * (1) "Last token is a functio=
n macro in __VA_ARGS__" is an issue both</span>
<span style=3D"color:rgb(137,136,135)"> * identifiers (__VA_NARGS__ and=
__VA_COMMA__) deal with reducing the amount</span>
<span style=3D"color:rgb(137,136,135)"> * of constructs necessary when =
checking for the empty preprocessor token.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * Notice that if the last token in =
__VA_ARGS__ is a defined function macro,</span>
<span style=3D"color:rgb(137,136,135)"> * the balanced parenthesis token fo=
llowing it would result in invoking said</span>
<span style=3D"color:rgb(137,136,135)"> * macro, therefore providing unexpe=
cted results. Current ways of bypassing</span>
<span style=3D"color:rgb(137,136,135)"> * this particular problem are avail=
able requiring greater complexity in</span>
<span style=3D"color:rgb(137,136,135)"> * the preprocessor constructs invol=
ved but are not presented here because they</span>
<span style=3D"color:rgb(137,136,135)"> * are out of the purpose of this de=
monstration.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * (2) "First token is a balanc=
ed parenthesis in __VA_ARGS__" is an issue both</span>
<span style=3D"color:rgb(137,136,135)"> * identifiers (__VA_NARGS__ and=
__VA_COMMA__) deal with reducing the amount</span>
<span style=3D"color:rgb(137,136,135)"> * of constructs necessary when =
checking for the empty preprocessor token.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * (3) __VA_NARGS__ and __VA_COMMA__=
are equivalent for their primary purposes</span>
<span style=3D"color:rgb(137,136,135)"> * but both require additional pr=
eprocessor metaprogramming constructs when</span>
<span style=3D"color:rgb(137,136,135)"> * used for detecting __VA_ARGS__=
expansion to the empty preprocessor token.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * If the hypothetical __VA_NARGS__ =
identifier was used, it would yield a token</span>
<span style=3D"color:rgb(137,136,135)"> * starting with a digit, thus invoc=
ation of MACRO_EMPTY_0 would not occur. The</span>
<span style=3D"color:rgb(137,136,135)"> * same holds for the hypothetical _=
_VA_COMMA__. Both expansions of said</span>
<span style=3D"color:rgb(137,136,135)"> * identifiers yield tokens that cou=
ld have not been used as identifiers</span>
<span style=3D"color:rgb(137,136,135)"> * themselves (that is in #define st=
atements) thus resolving the "last token</span>
<span style=3D"color:rgb(137,136,135)"> * is a function macro in __VA_ARGS_=
_" issue as presented in (1).</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * (4) __VA_COMMA__ by definition ex=
pands only to a single comma if and only if</span>
<span style=3D"color:rgb(137,136,135)"> * __VA_ARGS__ does not expand t=
o the empty token which means that it has</span>
<span style=3D"color:rgb(137,136,135)"> * unambiguous meaning over __VA=
_NARGS__ when it comes to handling said</span>
<span style=3D"color:rgb(137,136,135)"> * token, due to the definition =
of the "no arguments" token in C99 =A76.10.3p4</span>
<span style=3D"color:rgb(137,136,135)"> * and C++11 =A716.3p4. Thus, th=
e notational advantage of __VA_NARGS__ in</span>
<span style=3D"color:rgb(137,136,135)"> * providing argument count</spa=
n>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * This means that __VA_NARGS__ can=
have different meanings for code constructs</span>
<span style=3D"color:rgb(137,136,135)"> * out of the realm of the preproce=
ssor when it comes to assuming the value</span>
<span style=3D"color:rgb(137,136,135)"> * "1" for both a single =
token (no commas) and the empty token. __VA_COMMA__</span>
<span style=3D"color:rgb(137,136,135)"> * expansion *is* the empty token u=
nambiguously if and only if __VA_ARGS__ is,</span>
<span style=3D"color:rgb(137,136,135)"> * in all other cases it expands to=
a comma.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * (5) __VA_COMMA__ takes away the n=
eed for a (, ##__VA_ARGS__) extension with</span>
<span style=3D"color:rgb(137,136,135)"> * no additional constructs requ=
ired, while __VA_NARGS__ requires them in</span>
<span style=3D"color:rgb(137,136,135)"> * order to do so but may be amb=
iguous because of (4).</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * __VA__COMMA__ __VA_ARGS__ : =
a comma precedes __VA_ARGS__ if and only if</span>
<span style=3D"color:rgb(137,136,135)"> * =
__VA_ARGS__ does not expand to the empty</span>
<span style=3D"color:rgb(137,136,135)"> * =
preprocessor token.</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> * X(__VA_NARGS__) __VA_ARGS__: =
X would have to be a macro that would</span>
<span style=3D"color:rgb(137,136,135)"> * =
expand to a comma if __VA_NARGS__ was 0,</span>
<span style=3D"color:rgb(137,136,135)"> * =
but because of (4) such a macro may be</span>
<span style=3D"color:rgb(137,136,135)"> * =
unfeasible to implement if __VA_NARGS__</span>
<span style=3D"color:rgb(137,136,135)"> * =
has to resolve to the minimum of "1".</span>
<span style=3D"color:rgb(137,136,135)"> * </span>
<span style=3D"color:rgb(137,136,135)"> */</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_0 0</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_1 1,</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_0() 1,</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_MACRO_EMPTY_0 0,</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_1(...) MACRO_EMPTY_2=
(__VA_ARGS__)</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_2(...) MACRO_EMPTY_3=
(MACRO_ ## __VA_ARGS__)</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_3(...) MACRO_EMPTY_4=
(__VA_ARGS__)</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_4(x,...) x</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_5() 0,</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_MACRO_EMPTY_5 1,</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_6(x,y) MACRO_EMPTY_7=
(x,y)</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_7(x,y) MACRO_EMPTY_#=
#x##y()</span>
<span style=3D"color:rgb(137,136,135)">/* This is an implementation of the =
AND logic gate */</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_00() 0</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_10() 0</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_11() 1</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY_01() 0</span>
<span style=3D"color:rgb(137,136,135)">/**</span>
<span style=3D"color:rgb(137,136,135)"> * The actual macro for checking for=
the "empty" token provided (1) does not</span>
<span style=3D"color:rgb(137,136,135)"> * apply, because (1) would require =
a more complicated version and of course</span>
<span style=3D"color:rgb(137,136,135)"> * is what __VA_NARGS__ / __VA_COMMA=
__ would deal with best, making a lot of</span>
<span style=3D"color:rgb(137,136,135)"> * the macros defined above pointles=
s.</span>
<span style=3D"color:rgb(137,136,135)"> */</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_EMPTY(...) \</span>
<span style=3D"color:rgb(7,47,87)"> MACRO_EMPTY_6( MACRO_EMPTY_1(MAC=
RO_EMPTY_0 __VA_ARGS__ ()) \</span>
<span style=3D"color:rgb(7,47,87)"> , MACRO_EMPTY_1(MAC=
RO_EMPTY_5 __VA_ARGS__,) )</span>
<span style=3D"color:rgb(137,136,135)">/**</span>
<span style=3D"color:rgb(137,136,135)"> * Using string concatenation for im=
plementing an expression evaluation of</span>
<span style=3D"color:rgb(137,136,135)"> * sorts, preprocessor - wise. Combi=
ning the following with a recursion and</span>
<span style=3D"color:rgb(137,136,135)"> * an addition construct can yield t=
he number of tokens in a comma separated</span>
<span style=3D"color:rgb(137,136,135)"> * list of preprocessor tokens. This=
means that at a cost, __VA_NARGS__ could</span>
<span style=3D"color:rgb(137,136,135)"> * be implemented as VA_NARGS(...) u=
sing preprocessor metaprogramming. The</span>
<span style=3D"color:rgb(137,136,135)"> * techniques involved for this vary=
, but outside naive implementations require</span>
<span style=3D"color:rgb(137,136,135)"> * few lines for several hundred (an=
d more) tokens to be accounted for.</span>
<span style=3D"color:rgb(137,136,135)"> */</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_IFELSE(x,y,z) MACRO_IFELS=
E_(x,y,z)</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_IFELSE_(x,y,z) MACRO_IFELS=
E##x(y,z)</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_IFELSE1(y,z) y</span>
<span style=3D"color:rgb(7,47,87)">#define MACRO_IFELSE0(y,z) z</span>
<span style=3D"color:rgb(0,87,174)">int</span> main() {
<span style=3D"color:rgb(137,136,135)">// full !</span>
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n</span><span style=3D"color:rgb(191,3,3)">"<=
/span> , MACRO_IFELSE(MACRO_EMPTY(a),<span style=3D"color:rgb(191,3,3)">&q=
uot;null"</span>,<span style=3D"color:rgb(191,3,3)">"full"</=
span>));
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n</span><span style=3D"color:rgb(191,3,3)">"<=
/span> , MACRO_IFELSE(MACRO_EMPTY(a,b),<span style=3D"color:rgb(191,3,3)">=
"null"</span>,<span style=3D"color:rgb(191,3,3)">"full"=
</span>));
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n</span><span style=3D"color:rgb(191,3,3)">"<=
/span> , MACRO_IFELSE(MACRO_EMPTY(,),<span style=3D"color:rgb(191,3,3)">&q=
uot;null"</span>,<span style=3D"color:rgb(191,3,3)">"full"</=
span>));
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n</span><span style=3D"color:rgb(191,3,3)">"<=
/span> , MACRO_IFELSE(MACRO_EMPTY(()),<span style=3D"color:rgb(191,3,3)">&=
quot;null"</span>,<span style=3D"color:rgb(191,3,3)">"full"<=
/span>));
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n</span><span style=3D"color:rgb(191,3,3)">"<=
/span> , MACRO_IFELSE(MACRO_EMPTY(+),<span style=3D"color:rgb(191,3,3)">&q=
uot;null"</span>,<span style=3D"color:rgb(191,3,3)">"full"</=
span>));
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n</span><span style=3D"color:rgb(191,3,3)">"<=
/span> , MACRO_IFELSE(MACRO_EMPTY([]),<span style=3D"color:rgb(191,3,3)">&=
quot;null"</span>,<span style=3D"color:rgb(191,3,3)">"full"<=
/span>));
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n\n</span><span style=3D"color:rgb(191,3,3)">"=
;</span>, MACRO_IFELSE(MACRO_EMPTY(!),<span style=3D"color:rgb(191,3,3)">&q=
uot;null"</span>,<span style=3D"color:rgb(191,3,3)">"full"</=
span>));
<span style=3D"color:rgb(137,136,135)">// null, i.e. the empty token, w=
hich is actually "argument count 1" for what</span>
<span style=3D"color:rgb(137,136,135)">// the preprocessor is concerned=
but that not may always be for what the</span>
<span style=3D"color:rgb(137,136,135)">// end user is concerned. __VA_C=
OMMA__ has an advantage over such an</span>
<span style=3D"color:rgb(137,136,135)">// occasion as well since it wou=
ld allow the end user to take that</span>
<span style=3D"color:rgb(137,136,135)">// decision for his / her own ne=
eds.</span>
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n</span><span style=3D"color:rgb(191,3,3)">"<=
/span>, MACRO_IFELSE(MACRO_EMPTY(<span style=3D"color:rgb(137,136,135)">/**=
/</span>),<span style=3D"color:rgb(191,3,3)">"null"</span>,<span =
style=3D"color:rgb(191,3,3)">"full"</span>));
printf(<span style=3D"color:rgb(191,3,3)">"%s</span><span style=3D=
"color:rgb(146,76,157)">\n</span><span style=3D"color:rgb(191,3,3)">"<=
/span>, MACRO_IFELSE(MACRO_EMPTY(),<span style=3D"color:rgb(191,3,3)">"=
;null"</span>,<span style=3D"color:rgb(191,3,3)">"full"</spa=
n>));
<b>return</b> {};
}
</pre>[segment ends]<br></div></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b67888069529204e9d1d6a5--
.
Author: stackmachine@hotmail.com
Date: Mon, 28 Oct 2013 12:49:31 -0700 (PDT)
Raw View
------=_Part_1447_22129495.1382989772211
Content-Type: text/plain; charset=ISO-8859-1
Why not instead try to get rid of macros instead by providing a better
replacement in the language?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1447_22129495.1382989772211
Content-Type: text/html; charset=ISO-8859-1
<div dir="ltr">Why not instead try to get rid of macros instead by providing a better replacement in the language?<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
------=_Part_1447_22129495.1382989772211--
.
Author: George Makrydakis <irrequietus@gmail.com>
Date: Mon, 28 Oct 2013 22:01:49 +0200
Raw View
------022MVSAIX41FHGQTQ33AIH4SU5AARD
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Eventually, as we have said previously, that could and should happen.
But it is a different game all together. Likely to happen after modules eli=
minate the need for inclusion directives, which would force preprocessing m=
ore into the generative metaprogramming realm and thus towards the need for=
expression tree friendly macros.
For the time being though, one must use what is available. Despite its shor=
tcomings the preprocessor is far from being a weakling for code generation,=
if used properly.
stackmachine@hotmail.com wrote:
>Why not instead try to get rid of macros instead by providing a better=20
>replacement in the language ?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------022MVSAIX41FHGQTQ33AIH4SU5AARD
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<html><head></head><body><p dir=3D"ltr">Eventually, as we have said previou=
sly, that could and should happen.</p>
<p dir=3D"ltr">But it is a different game all together. Likely to happen af=
ter modules eliminate the need for inclusion directives, which would force =
preprocessing more into the generative metaprogramming realm and thus towar=
ds the need for expression tree friendly macros.</p>
<p dir=3D"ltr">For the time being though, one must use what is available. D=
espite its shortcomings the preprocessor is far from being a weakling for c=
ode generation, if used properly.</p>
<br><br><div class=3D"gmail_quote">stackmachine@hotmail.com wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1=
px solid rgb(204, 204, 204); padding-left: 1ex;">
<div dir=3D"ltr">Why not instead try to get rid of macros instead by provid=
ing a better replacement in the language?<br /></div>
<p></p>
</blockquote></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------022MVSAIX41FHGQTQ33AIH4SU5AARD--
.
Author: David Krauss <potswa@gmail.com>
Date: Tue, 29 Oct 2013 13:09:09 +0800
Raw View
On 10/29/13 3:49 AM, stackmachine@hotmail.com wrote:
> Why not instead try to get rid of macros instead by providing a better
> replacement in the language?
We do, they're called templates. Also... The difference between a gadfly
and a troll is that one has a contribution (perhaps unpopular), and the
other just sits around tossing insults and contradiction for cheap
attention.
Macros are a catch-all for whatever no better-specified construct can
do, and the more formally clean the replacement is, the narrower its
usage must be. We probably don't need something entirely new to fill the
niche between macros and templates, but rather to improve the language
to obviate the use cases of macros. However, all else equal, it's a
higher priority to add a feature to the language that macros *can't*
already implement.
Can someone enlighten us on what the use case for this __VA_NARGS__
would be? Preprocessor metaprogramming isn't really a domain of clean
interfaces. For those who are really serious about trying, won't they
just use Boost.PP? Is it worthwhile to build conveniences into the
language that are redundant with Boost.PP?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: George Makrydakis <irrequietus@gmail.com>
Date: Tue, 29 Oct 2013 08:51:56 +0200
Raw View
------A1S3YYA9AIEAT12U7ZC3IX2N9G4UW9
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Extending the preprocessor by correcting minor inefficiencies should not be=
actually considered equivalent trying to replace it with a new "kind" of p=
reprocessor, that would be a step backwards.
Both template and constexpr metaprogramming are extremely important in elim=
inating plain text substitution macros but nowadays we use the preprocessor=
for systematically generating complex code constructs to be used in a post=
- preprocessing phase that would be tedious to do otherwise. As an example=
I cite the way template variadicity was emulated in C++03. Now that variad=
ic templates are around, there is obviously no need for that solution.
However, the language has not yet reached a point where that kind of use of=
the preprocessor as a crutch in implementing complicated post - preprocess=
ing phase constructs is no longer required. It is inevitable that it will, =
especially once modules eliminate the need for inclusion directives, thus d=
epriving the preprocessor another of its reasons for being.
That being said, it is evident that you find me in agreement. Let's get bac=
k to morwenn's __VA_NARGS__ though.
Implementing __VA__NARGS__ would be more into trying to keep alive the prep=
rocessor eventually as well as introducing ambiguities nobody would serious=
ly want or even ending up paving the way for discussing expression evaluati=
ons out of the conditional directives.=20
This is why I would not in the end really find a reason for it to exist.
On the other hand, __VA_COMMA__ is all about a builtin identifier added for=
making detection of the empty token easier and more importantly compromise=
- free. The fact of it being usable for assisting in the implementation of=
macro argument counting is merely an extension of it being such a detector=
of the empty token within the context of recursive macro constructs and no=
thing more.
Personally I can deal with not having __VA_COMMA__ either, but that does no=
t mean that I would not discuss about it as a counterpoint to an eventual _=
_VA_NARGS__ and its inconsistencies, since it would introduce none.
In a previous post I have already pointed out that either should be discuss=
ed before considering anything as engaging as a proposal.
This thread is about dissecting __VA_NARGS__ anyway and through the discuss=
ion it is crystal clear that it would not be the best solution to any probl=
em regardless of the future of the preprocessor.
In the end that solution would be to obviate the need not just for plain ma=
cros, but for preprocessor metaprogramming altogether even where it is used=
as a crutch. That would be the topic for another long and meaningful threa=
d.
David Krauss <potswa@gmail.com> wrote:
>On 10/29/13 3:49 AM, stackmachine@hotmail.com wrote:
>> Why not instead try to get rid of macros instead by providing a
>better
>> replacement in the language?
>We do, they're called templates. Also... The difference between a
>gadfly=20
>and a troll is that one has a contribution (perhaps unpopular), and the
>
>other just sits around tossing insults and contradiction for cheap=20
>attention.
>
>Macros are a catch-all for whatever no better-specified construct can=20
>do, and the more formally clean the replacement is, the narrower its=20
>usage must be. We probably don't need something entirely new to fill
>the=20
>niche between macros and templates, but rather to improve the language=20
>to obviate the use cases of macros. However, all else equal, it's a=20
>higher priority to add a feature to the language that macros *can't*=20
>already implement.
>
>Can someone enlighten us on what the use case for this __VA_NARGS__=20
>would be? Preprocessor metaprogramming isn't really a domain of clean=20
>interfaces. For those who are really serious about trying, won't they=20
>just use Boost.PP? Is it worthwhile to build conveniences into the=20
>language that are redundant with Boost.PP?
>
>--=20
>
>---=20
>You received this message because you are subscribed to the Google
>Groups "ISO C++ Standard - Future Proposals" group.
>To unsubscribe from this group and stop receiving emails from it, send
>an email to std-proposals+unsubscribe@isocpp.org.
>To post to this group, send email to std-proposals@isocpp.org.
>Visit this group at
>http://groups.google.com/a/isocpp.org/group/std-proposals/.
--=20
Sent from Kaiten Mail. Please excuse my brevity.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------A1S3YYA9AIEAT12U7ZC3IX2N9G4UW9
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<html><head></head><body><p dir=3D"ltr">Extending the preprocessor by corre=
cting minor inefficiencies should not be actually considered equivalent try=
ing to replace it with a new "kind" of preprocessor, that would be a step b=
ackwards.</p>
<p dir=3D"ltr">Both template and constexpr metaprogramming are extremely im=
portant in eliminating plain text substitution macros but nowadays we use t=
he preprocessor for systematically generating complex code constructs to be=
used in a post - preprocessing phase that would be tedious to do otherwise=
.. As an example I cite the way template variadicity was emulated in C++03. =
Now that variadic templates are around, there is obviously no need for that=
solution.</p>
<p dir=3D"ltr">However, the language has not yet reached a point where that=
kind of use of the preprocessor as a crutch in implementing complicated po=
st - preprocessing phase constructs is no longer required. It is inevitable=
that it will, especially once modules eliminate the need for inclusion dir=
ectives, thus depriving the preprocessor another of its reasons for being.<=
/p>
<p dir=3D"ltr">That being said, it is evident that you find me in agreement=
.. Let's get back to morwenn's __VA_NARGS__ though.</p>
<p dir=3D"ltr">Implementing __VA__NARGS__ would be more into trying to keep=
alive the preprocessor eventually as well as introducing ambiguities nobod=
y would seriously want or even ending up paving the way for discussing expr=
ession evaluations out of the conditional directives. </p>
<p dir=3D"ltr">This is why I would not in the end really find a reason for =
it to exist.</p>
<p dir=3D"ltr">On the other hand, __VA_COMMA__ is all about a builtin ident=
ifier added for making detection of the empty token easier and more importa=
ntly compromise - free. The fact of it being usable for assisting in the im=
plementation of macro argument counting is merely an extension of it being =
such a detector of the empty token within the context of recursive macro co=
nstructs and nothing more.</p>
<p dir=3D"ltr">Personally I can deal with not having __VA_COMMA__ either, b=
ut that does not mean that I would not discuss about it as a counterpoint t=
o an eventual __VA_NARGS__ and its inconsistencies, since it would introduc=
e none.</p>
<p dir=3D"ltr">In a previous post I have already pointed out that either sh=
ould be discussed before considering anything as engaging as a proposal.</p=
>
<p dir=3D"ltr">This thread is about dissecting __VA_NARGS__ anyway and thro=
ugh the discussion it is crystal clear that it would not be the best soluti=
on to any problem regardless of the future of the preprocessor.</p>
<p dir=3D"ltr">In the end that solution would be to obviate the need not ju=
st for plain macros, but for preprocessor metaprogramming altogether even w=
here it is used as a crutch. That would be the topic for another long and m=
eaningful thread.<br>
</p>
<br><br><div class=3D"gmail_quote">David Krauss <potswa@gmail.com> wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; b=
order-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class=3D"k9mail">On 10/29/13 3:49 AM, stackmachine@hotmail.com wrote:<=
br /><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 1ex 0.8ex; =
border-left: 1px solid #729fcf; padding-left: 1ex;"> Why not instead try to=
get rid of macros instead by providing a better<br /> replacement in the l=
anguage?<br /></blockquote>We do, they're called templates. Also... The dif=
ference between a gadfly <br />and a troll is that one has a contribution (=
perhaps unpopular), and the <br />other just sits around tossing insults an=
d contradiction for cheap <br />attention.<br /><br />Macros are a catch-al=
l for whatever no better-specified construct can <br />do, and the more for=
mally clean the replacement is, the narrower its <br />usage must be. We pr=
obably don't need something entirely new to fill the <br />niche between ma=
cros and templates, but rather to improve the language <br />to obviate the=
use cases of macros. However, all else equal, it's a <br />higher priority=
to add a feature to the
language that macros *can't* <br />already implement.<br /><br />Can someon=
e enlighten us on what the use case for this __VA_NARGS__ <br />would be? P=
reprocessor metaprogramming isn't really a domain of clean <br />interfaces=
.. For those who are really serious about trying, won't they <br />just use =
Boost.PP? Is it worthwhile to build conveniences into the <br />language th=
at are redundant with Boost.PP?<br /></pre></blockquote></div><br>
-- <br>
Sent from Kaiten Mail. Please excuse my brevity.</body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------A1S3YYA9AIEAT12U7ZC3IX2N9G4UW9--
.