Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.std.c > #6430 > unrolled thread
| Started by | Kaz Kylheku <480-992-1380@kylheku.com> |
|---|---|
| First post | 2022-04-14 00:01 +0000 |
| Last post | 2022-05-14 10:35 -0700 |
| Articles | 7 — 3 participants |
Back to article view | Back to comp.std.c
Why doesn't __VA_LIST__ just eat the prior comma? Kaz Kylheku <480-992-1380@kylheku.com> - 2022-04-14 00:01 +0000
Re: Why doesn't __VA_LIST__ just eat the prior comma? Ben <ben.usenet@bsb.me.uk> - 2022-04-14 14:17 +0100
Re: Why doesn't __VA_LIST__ just eat the prior comma? Kaz Kylheku <480-992-1380@kylheku.com> - 2022-04-18 16:59 +0000
Re: Why doesn't __VA_LIST__ just eat the prior comma? Ben <ben.usenet@bsb.me.uk> - 2022-04-18 20:43 +0100
Re: Why doesn't __VA_LIST__ just eat the prior comma? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-19 02:04 -0700
Re: Why doesn't __VA_LIST__ just eat the prior comma? Kaz Kylheku <480-992-1380@kylheku.com> - 2022-04-20 02:02 +0000
Re: Why doesn't __VA_LIST__ just eat the prior comma? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-05-14 10:35 -0700
| From | Kaz Kylheku <480-992-1380@kylheku.com> |
|---|---|
| Date | 2022-04-14 00:01 +0000 |
| Subject | Why doesn't __VA_LIST__ just eat the prior comma? |
| Message-ID | <20220413165157.844@kylheku.com> |
There is a well-known problem that a macro like #define foo(x, ...) something(whatever, __VA_ARGS__) cannot work when the trailing argument list is empty because you get the expansion something(whatever, ) GNU C provides ##__VA_ARGS__ which behaves like __VA_ARGS__ in the nonempty case, and eats the prior comma in the empty case. C++20 provides __VA_OPT__ which is used like __VA_OPT__(,) to conditionally eat the comma. (GNU C has this also). The question is: why wouldn't you just fix the semantics of __VA_ARG__ so that this is not necessary? When would you ever want to interpolate __VA_ARGS__ into a replacement sequence such that if it is empty, and placed after a comma, that comma does not disappear? -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
[toc] | [next] | [standalone]
| From | Ben <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2022-04-14 14:17 +0100 |
| Message-ID | <87czhju7ml.fsf@bsb.me.uk> |
| In reply to | #6430 |
Kaz Kylheku <480-992-1380@kylheku.com> writes: > There is a well-known problem that a macro like > > #define foo(x, ...) something(whatever, __VA_ARGS__) > > cannot work when the trailing argument list is empty because > you get the expansion something(whatever, ) > > GNU C provides ##__VA_ARGS__ which behaves like __VA_ARGS__ in > the nonempty case, and eats the prior comma in the empty case. > > C++20 provides __VA_OPT__ which is used like __VA_OPT__(,) to > conditionally eat the comma. (GNU C has this also). > > The question is: why wouldn't you just fix the semantics of __VA_ARG__ > so that this is not necessary? > > When would you ever want to interpolate __VA_ARGS__ into a replacement > sequence such that if it is empty, and placed after a comma, that > comma does not disappear? You might not want it (as a design feature), but there is probably code out there that now depends on it. The C committee is very reluctant to break existing code, especially where the fix is more complex than "search for 'restrict' to check it's not used". -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <480-992-1380@kylheku.com> |
|---|---|
| Date | 2022-04-18 16:59 +0000 |
| Message-ID | <20220418093916.295@kylheku.com> |
| In reply to | #6431 |
On 2022-04-14, Ben <ben.usenet@bsb.me.uk> wrote:
> Kaz Kylheku <480-992-1380@kylheku.com> writes:
>
>> There is a well-known problem that a macro like
>>
>> #define foo(x, ...) something(whatever, __VA_ARGS__)
>>
>> cannot work when the trailing argument list is empty because
>> you get the expansion something(whatever, )
>>
>> GNU C provides ##__VA_ARGS__ which behaves like __VA_ARGS__ in
>> the nonempty case, and eats the prior comma in the empty case.
>>
>> C++20 provides __VA_OPT__ which is used like __VA_OPT__(,) to
>> conditionally eat the comma. (GNU C has this also).
>>
>> The question is: why wouldn't you just fix the semantics of __VA_ARG__
>> so that this is not necessary?
>>
>> When would you ever want to interpolate __VA_ARGS__ into a replacement
>> sequence such that if it is empty, and placed after a comma, that
>> comma does not disappear?
>
> You might not want it (as a design feature), but there is probably code
> out there that now depends on it.
That's my question: what is the form of this dependency? What is an
example of something that breaks if __VA_ARGS__ eats the prior comma
when it has an empty expansion?
Of course, we can write regression test cases which verify that
the comma is not eaten, and I can think of ways of doing that:
#define mac(...) foo(, __VA_ARGS__)
#define xstr(x) str(x)
#define str(x) #x
assert (strcmp(xstr(mac()), "foo(, )") == 0);
printf("%s\n", xstr(mac()));
I mean, some way of relying on the comma that is actually useful.
If I wanted to stringify mac() for some useful purpose in some real
program, I would actually prefer the result "foo( )" or "foo()".
I'd likely need a post-processing run-time pass to convert "(, )"
occurrences to "()". I'd probably have some conditionals to do it
in the preprocessor, so that the post-processing code can be
compiled out.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
[toc] | [prev] | [next] | [standalone]
| From | Ben <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2022-04-18 20:43 +0100 |
| Message-ID | <87bkwygotu.fsf@bsb.me.uk> |
| In reply to | #6432 |
Kaz Kylheku <480-992-1380@kylheku.com> writes:
> On 2022-04-14, Ben <ben.usenet@bsb.me.uk> wrote:
>> Kaz Kylheku <480-992-1380@kylheku.com> writes:
>>
>>> There is a well-known problem that a macro like
>>>
>>> #define foo(x, ...) something(whatever, __VA_ARGS__)
>>>
>>> cannot work when the trailing argument list is empty because
>>> you get the expansion something(whatever, )
>>>
>>> GNU C provides ##__VA_ARGS__ which behaves like __VA_ARGS__ in
>>> the nonempty case, and eats the prior comma in the empty case.
>>>
>>> C++20 provides __VA_OPT__ which is used like __VA_OPT__(,) to
>>> conditionally eat the comma. (GNU C has this also).
>>>
>>> The question is: why wouldn't you just fix the semantics of __VA_ARG__
>>> so that this is not necessary?
>>>
>>> When would you ever want to interpolate __VA_ARGS__ into a replacement
>>> sequence such that if it is empty, and placed after a comma, that
>>> comma does not disappear?
>>
>> You might not want it (as a design feature), but there is probably code
>> out there that now depends on it.
>
> That's my question: what is the form of this dependency? What is an
> example of something that breaks if __VA_ARGS__ eats the prior comma
> when it has an empty expansion?
I don't know of an example.
> Of course, we can write regression test cases which verify that
> the comma is not eaten, and I can think of ways of doing that:
>
> #define mac(...) foo(, __VA_ARGS__)
> #define xstr(x) str(x)
> #define str(x) #x
>
> assert (strcmp(xstr(mac()), "foo(, )") == 0);
>
> printf("%s\n", xstr(mac()));
>
> I mean, some way of relying on the comma that is actually useful.
The code does not have to find it actually useful for it to break on a
change. If someone, somewhere, ended up having to work around this
issue, that code will break even if the programmer might now be glad of
the opportunity to simplify it.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-04-19 02:04 -0700 |
| Message-ID | <861qxta1gb.fsf@linuxsc.com> |
| In reply to | #6430 |
Kaz Kylheku <480-992-1380@kylheku.com> writes:
> There is a well-known problem that a macro like
>
> #define foo(x, ...) something(whatever, __VA_ARGS__)
>
> cannot work when the trailing argument list is empty because
> you get the expansion something(whatever, )
>
> GNU C provides ##__VA_ARGS__ which behaves like __VA_ARGS__ in
> the nonempty case, and eats the prior comma in the empty case.
>
> C++20 provides __VA_OPT__ which is used like __VA_OPT__(,) to
> conditionally eat the comma. (GNU C has this also).
>
> The question is: why wouldn't you just fix the semantics of
> __VA_ARG__ so that this is not necessary?
This idea is considered in section "Alternative Designs" of
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2160.htm
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <480-992-1380@kylheku.com> |
|---|---|
| Date | 2022-04-20 02:02 +0000 |
| Message-ID | <20220419183244.563@kylheku.com> |
| In reply to | #6434 |
On 2022-04-19, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> Kaz Kylheku <480-992-1380@kylheku.com> writes:
>
>> There is a well-known problem that a macro like
>>
>> #define foo(x, ...) something(whatever, __VA_ARGS__)
>>
>> cannot work when the trailing argument list is empty because
>> you get the expansion something(whatever, )
>>
>> GNU C provides ##__VA_ARGS__ which behaves like __VA_ARGS__ in
>> the nonempty case, and eats the prior comma in the empty case.
>>
>> C++20 provides __VA_OPT__ which is used like __VA_OPT__(,) to
>> conditionally eat the comma. (GNU C has this also).
>>
>> The question is: why wouldn't you just fix the semantics of
>> __VA_ARG__ so that this is not necessary?
>
> This idea is considered in section "Alternative Designs" of
>
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2160.htm
Fantastic; thanks for that link!
The crux is that, for whatever reason, a macro like:
#define ADD_COMMA(...) , __VA_ARGS__
is tabled as an important requirement, and for that reason, F()
expanding to f(10), though identified as desirable, is not considered;
the automatic comma eating would break ADD_COMMA.
But! I think that could be acceptably handled like this:
#define FENCE
#define ADD_COMMA(...) , FENCE __VA_ARGS__
The rule that __VA_ARGS__ consumes the comma would be carried out
prior to the macro replacement of the token replacement sequence,
during which time FENCE is still there. Since FENCE doesn't look like
a comma, all is cool.
(This seems natural because the substitution of __VA_ARGS__ should in fact
be taking place during argument replacement, and not during the
rescanning of the argument-substituted replacement sequence for more
macros.)
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-05-14 10:35 -0700 |
| Message-ID | <86a6bk3tm7.fsf@linuxsc.com> |
| In reply to | #6435 |
Kaz Kylheku <480-992-1380@kylheku.com> writes: > On 2022-04-19, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote: > >> Kaz Kylheku <480-992-1380@kylheku.com> writes: >> >>> There is a well-known problem that a macro like >>> >>> #define foo(x, ...) something(whatever, __VA_ARGS__) >>> >>> cannot work when the trailing argument list is empty because >>> you get the expansion something(whatever, ) >>> >>> GNU C provides ##__VA_ARGS__ which behaves like __VA_ARGS__ in >>> the nonempty case, and eats the prior comma in the empty case. >>> >>> C++20 provides __VA_OPT__ which is used like __VA_OPT__(,) to >>> conditionally eat the comma. (GNU C has this also). >>> >>> The question is: why wouldn't you just fix the semantics of >>> __VA_ARG__ so that this is not necessary? >> >> This idea is considered in section "Alternative Designs" of >> >> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2160.htm > > Fantastic; thanks for that link! > > The crux is that, for whatever reason, a macro like: > > #define ADD_COMMA(...) , __VA_ARGS__ > > is tabled as an important requirement, and for that reason, F() > expanding to f(10), though identified as desirable, is not > considered; the automatic comma eating would break ADD_COMMA. > > But! I think that could be acceptably handled like this: > > #define FENCE > #define ADD_COMMA(...) , FENCE __VA_ARGS__ > > The rule that __VA_ARGS__ consumes the comma would be carried out > prior to the macro replacement of the token replacement sequence, > during which time FENCE is still there. Since FENCE doesn't look > like a comma, all is cool. If you feel strongly about it, write up a proposal and submit it to the two committees. Given that __VA_OPT__ has already been adopted in C++20, any alternate scheme faces an uphill climb, and so if no one feels strongly enough to try to get some other scheme through the standardization process then it seems rather pointless to discuss it.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.std.c
csiph-web