public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Possible __VA_OPT__ bug
@ 2019-10-31 16:43 Edward Diener
  2019-10-31 17:15 ` Segher Boessenkool
  2019-11-01 14:39 ` Edward Diener
  0 siblings, 2 replies; 8+ messages in thread
From: Edward Diener @ 2019-10-31 16:43 UTC (permalink / raw)
  To: gcc-help

Given:

#define NO_DATA
#define TRY_VA_OPT(...)  __VA_OPT__ (0) 1

TRY_VA_OPT() -> expands to 1 as expected
TRY_VA_OPT(NO_DATA) -> expands to 0 1 which is not expected

when compiled with gcc-9.2 with -std=c++2a.

I have not tested with gcc-8.1 on up at all C++ standard levels, as 
__VA_OPT__ is supported there also, but I expect the same results will 
occur.

I see no reason why both do not expand to 1. Is this a gcc bug ? If so, 
I will report it to gcc. If not can anyone explain the second output ?

The command line parameters i used are:

-fvisibility-inlines-hidden -fPIC -m64 -pthread -O0 -fno-inline -Wall 
-Wextra -pedantic -g -fvisibility=hidden -Wno-variadic-macros 
-ftrack-macro-expansion=0 -std=c++2a


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible __VA_OPT__ bug
  2019-10-31 16:43 Possible __VA_OPT__ bug Edward Diener
@ 2019-10-31 17:15 ` Segher Boessenkool
  2019-10-31 18:50   ` Edward Diener
  2019-11-01 14:39 ` Edward Diener
  1 sibling, 1 reply; 8+ messages in thread
From: Segher Boessenkool @ 2019-10-31 17:15 UTC (permalink / raw)
  To: Edward Diener; +Cc: gcc-help

Hi Edward,

On Thu, Oct 31, 2019 at 12:42:54PM -0400, Edward Diener wrote:
> Given:
> 
> #define NO_DATA
> #define TRY_VA_OPT(...)  __VA_OPT__ (0) 1
> 
> TRY_VA_OPT() -> expands to 1 as expected
> TRY_VA_OPT(NO_DATA) -> expands to 0 1 which is not expected
> 
> when compiled with gcc-9.2 with -std=c++2a.

Why is that not expected?  The variadic macro TRY_VA_OPT does get tokens
in its variable argument (namely, NO_DATA), so __VA_OPT__ expands to its
argument (which is 0).

https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html


Segher

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible __VA_OPT__ bug
  2019-10-31 17:15 ` Segher Boessenkool
@ 2019-10-31 18:50   ` Edward Diener
  2019-10-31 20:21     ` Segher Boessenkool
  0 siblings, 1 reply; 8+ messages in thread
From: Edward Diener @ 2019-10-31 18:50 UTC (permalink / raw)
  To: gcc-help

On 10/31/2019 1:14 PM, Segher Boessenkool wrote:
> Hi Edward,
> 
> On Thu, Oct 31, 2019 at 12:42:54PM -0400, Edward Diener wrote:
>> Given:
>>
>> #define NO_DATA
>> #define TRY_VA_OPT(...)  __VA_OPT__ (0) 1
>>
>> TRY_VA_OPT() -> expands to 1 as expected
>> TRY_VA_OPT(NO_DATA) -> expands to 0 1 which is not expected
>>
>> when compiled with gcc-9.2 with -std=c++2a.
> 
> Why is that not expected?  The variadic macro TRY_VA_OPT does get tokens
> in its variable argument (namely, NO_DATA), so __VA_OPT__ expands to its
> argument (which is 0).
> 
> https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

The wording of 15.6.1 paragraph 3 is confusing to me. I had thought that 
the arguments to the variadic ... parameter were completely macro 
expanded before considering whether the __VA_OPT__ ( pp-tokens ) would 
expand to 'pp_tokens' or a single placemarker token. Evidently you are 
saying that the correct interpretation with the __VA_OPT__ construct is 
that the variadic ... arguments are not macro expanded before 
consideration of the __VA_OPT__ construct processing . This seems to me 
very odd because the arguments to the variadic ... parameter are always 
completely macro expanded before being replaced by any __VA_ARGS__ 
parameter in the replacement list. I wonder why the C++ standard 
committee decided to treat __VA_OPT__ differently from __VA_ARGS__ in 
this regard ?

> 
> 
> Segher
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible __VA_OPT__ bug
  2019-10-31 18:50   ` Edward Diener
@ 2019-10-31 20:21     ` Segher Boessenkool
  2019-10-31 20:28       ` Edward Diener
  0 siblings, 1 reply; 8+ messages in thread
From: Segher Boessenkool @ 2019-10-31 20:21 UTC (permalink / raw)
  To: Edward Diener; +Cc: gcc-help

On Thu, Oct 31, 2019 at 02:50:07PM -0400, Edward Diener wrote:
> On 10/31/2019 1:14 PM, Segher Boessenkool wrote:
> >On Thu, Oct 31, 2019 at 12:42:54PM -0400, Edward Diener wrote:
> >>Given:
> >>
> >>#define NO_DATA
> >>#define TRY_VA_OPT(...)  __VA_OPT__ (0) 1
> >>
> >>TRY_VA_OPT() -> expands to 1 as expected
> >>TRY_VA_OPT(NO_DATA) -> expands to 0 1 which is not expected
> >>
> >>when compiled with gcc-9.2 with -std=c++2a.
> >
> >Why is that not expected?  The variadic macro TRY_VA_OPT does get tokens
> >in its variable argument (namely, NO_DATA), so __VA_OPT__ expands to its
> >argument (which is 0).
> >
> >https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
> 
> The wording of 15.6.1 paragraph 3 is confusing to me. I had thought that 
> the arguments to the variadic ... parameter were completely macro 
> expanded before considering whether the __VA_OPT__ ( pp-tokens ) would 
> expand to 'pp_tokens' or a single placemarker token. Evidently you are 
> saying that the correct interpretation with the __VA_OPT__ construct is 
> that the variadic ... arguments are not macro expanded before 
> consideration of the __VA_OPT__ construct processing . This seems to me 
> very odd because the arguments to the variadic ... parameter are always 
> completely macro expanded before being replaced by any __VA_ARGS__ 
> parameter in the replacement list. I wonder why the C++ standard 
> committee decided to treat __VA_OPT__ differently from __VA_ARGS__ in 
> this regard ?

I don't know.  I don't know if the GCC implementation is correct, either.


Segher

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible __VA_OPT__ bug
  2019-10-31 20:21     ` Segher Boessenkool
@ 2019-10-31 20:28       ` Edward Diener
  2019-10-31 21:28         ` Jędrzej Dudkiewicz
  0 siblings, 1 reply; 8+ messages in thread
From: Edward Diener @ 2019-10-31 20:28 UTC (permalink / raw)
  To: gcc-help

On 10/31/2019 4:20 PM, Segher Boessenkool wrote:
> On Thu, Oct 31, 2019 at 02:50:07PM -0400, Edward Diener wrote:
>> On 10/31/2019 1:14 PM, Segher Boessenkool wrote:
>>> On Thu, Oct 31, 2019 at 12:42:54PM -0400, Edward Diener wrote:
>>>> Given:
>>>>
>>>> #define NO_DATA
>>>> #define TRY_VA_OPT(...)  __VA_OPT__ (0) 1
>>>>
>>>> TRY_VA_OPT() -> expands to 1 as expected
>>>> TRY_VA_OPT(NO_DATA) -> expands to 0 1 which is not expected
>>>>
>>>> when compiled with gcc-9.2 with -std=c++2a.
>>>
>>> Why is that not expected?  The variadic macro TRY_VA_OPT does get tokens
>>> in its variable argument (namely, NO_DATA), so __VA_OPT__ expands to its
>>> argument (which is 0).
>>>
>>> https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
>>
>> The wording of 15.6.1 paragraph 3 is confusing to me. I had thought that
>> the arguments to the variadic ... parameter were completely macro
>> expanded before considering whether the __VA_OPT__ ( pp-tokens ) would
>> expand to 'pp_tokens' or a single placemarker token. Evidently you are
>> saying that the correct interpretation with the __VA_OPT__ construct is
>> that the variadic ... arguments are not macro expanded before
>> consideration of the __VA_OPT__ construct processing . This seems to me
>> very odd because the arguments to the variadic ... parameter are always
>> completely macro expanded before being replaced by any __VA_ARGS__
>> parameter in the replacement list. I wonder why the C++ standard
>> committee decided to treat __VA_OPT__ differently from __VA_ARGS__ in
>> this regard ?
> 
> I don't know.  I don't know if the GCC implementation is correct, either.

Clang in its C++20 mode treats __VA_OPT__ as I thought it should be, 
where the determination of whether __VA_OPT__ ( pp-tokens ) expands to a 
placeholder token or pp-tokens is determined by whether the arguments 
for the variadic data parameter ... are empty or not after the arguments 
have been fully macro replaced. In other words clang expands to 1 in 
both my examples above.

> 
> 
> Segher
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible __VA_OPT__ bug
  2019-10-31 20:28       ` Edward Diener
@ 2019-10-31 21:28         ` Jędrzej Dudkiewicz
  2019-10-31 21:31           ` Jędrzej Dudkiewicz
  0 siblings, 1 reply; 8+ messages in thread
From: Jędrzej Dudkiewicz @ 2019-10-31 21:28 UTC (permalink / raw)
  To: Edward Diener; +Cc: gcc-help

On Thu, Oct 31, 2019 at 9:28 PM Edward Diener
<eldlistmailingz@tropicsoft.com> wrote:
>
> On 10/31/2019 4:20 PM, Segher Boessenkool wrote:
> > On Thu, Oct 31, 2019 at 02:50:07PM -0400, Edward Diener wrote:
> >> On 10/31/2019 1:14 PM, Segher Boessenkool wrote:
> >>> On Thu, Oct 31, 2019 at 12:42:54PM -0400, Edward Diener wrote:
> >>>> Given:
> >>>>
> >>>> #define NO_DATA
> >>>> #define TRY_VA_OPT(...)  __VA_OPT__ (0) 1
> >>>>
> >>>> TRY_VA_OPT() -> expands to 1 as expected
> >>>> TRY_VA_OPT(NO_DATA) -> expands to 0 1 which is not expected
> >>>>
> >>>> when compiled with gcc-9.2 with -std=c++2a.
> >>>
> >>> Why is that not expected?  The variadic macro TRY_VA_OPT does get tokens
> >>> in its variable argument (namely, NO_DATA), so __VA_OPT__ expands to its
> >>> argument (which is 0).
> >>>
> >>> https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
> >>
> >> The wording of 15.6.1 paragraph 3 is confusing to me. I had thought that
> >> the arguments to the variadic ... parameter were completely macro
> >> expanded before considering whether the __VA_OPT__ ( pp-tokens ) would
> >> expand to 'pp_tokens' or a single placemarker token. Evidently you are
> >> saying that the correct interpretation with the __VA_OPT__ construct is
> >> that the variadic ... arguments are not macro expanded before
> >> consideration of the __VA_OPT__ construct processing . This seems to me
> >> very odd because the arguments to the variadic ... parameter are always
> >> completely macro expanded before being replaced by any __VA_ARGS__
> >> parameter in the replacement list. I wonder why the C++ standard
> >> committee decided to treat __VA_OPT__ differently from __VA_ARGS__ in
> >> this regard ?
> >
> > I don't know.  I don't know if the GCC implementation is correct, either.
>
> Clang in its C++20 mode treats __VA_OPT__ as I thought it should be,
> where the determination of whether __VA_OPT__ ( pp-tokens ) expands to a
> placeholder token or pp-tokens is determined by whether the arguments
> for the variadic data parameter ... are empty or not after the arguments
> have been fully macro replaced. In other words clang expands to 1 in
> both my examples above.

#define T(a) #a
T(NO_DATA)

Expands to "NO_DATA", which means that it is:

T(NO_DATA) -> #NO_DATA -> "NO_DATA"

and not:

T(NO_DATA) -> T() -> <error, no argument>

Which explains why __VA_OPT__ behaves this way. According to godbolt
T(NO_DATA) also expands to "NO_DATA", which would mean that difference
between compilers boils down to checking if list is empty - gcc checks
it before macro expansion, and clang after expansion?
-- 
Jędrzej Dudkiewicz

I really hate this damn machine, I wish that they would sell it.
It never does just what I want, but only what I tell it.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible __VA_OPT__ bug
  2019-10-31 21:28         ` Jędrzej Dudkiewicz
@ 2019-10-31 21:31           ` Jędrzej Dudkiewicz
  0 siblings, 0 replies; 8+ messages in thread
From: Jędrzej Dudkiewicz @ 2019-10-31 21:31 UTC (permalink / raw)
  To: Edward Diener; +Cc: gcc-help

On Thu, Oct 31, 2019 at 10:27 PM Jędrzej Dudkiewicz
<jedrzej.dudkiewicz@gmail.com> wrote:
>
> On Thu, Oct 31, 2019 at 9:28 PM Edward Diener
> <eldlistmailingz@tropicsoft.com> wrote:
> >
> > On 10/31/2019 4:20 PM, Segher Boessenkool wrote:
> > > On Thu, Oct 31, 2019 at 02:50:07PM -0400, Edward Diener wrote:
> > >> On 10/31/2019 1:14 PM, Segher Boessenkool wrote:
> > >>> On Thu, Oct 31, 2019 at 12:42:54PM -0400, Edward Diener wrote:
> > >>>> Given:
> > >>>>
> > >>>> #define NO_DATA
> > >>>> #define TRY_VA_OPT(...)  __VA_OPT__ (0) 1
> > >>>>
> > >>>> TRY_VA_OPT() -> expands to 1 as expected
> > >>>> TRY_VA_OPT(NO_DATA) -> expands to 0 1 which is not expected
> > >>>>
> > >>>> when compiled with gcc-9.2 with -std=c++2a.
> > >>>
> > >>> Why is that not expected?  The variadic macro TRY_VA_OPT does get tokens
> > >>> in its variable argument (namely, NO_DATA), so __VA_OPT__ expands to its
> > >>> argument (which is 0).
> > >>>
> > >>> https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
> > >>
> > >> The wording of 15.6.1 paragraph 3 is confusing to me. I had thought that
> > >> the arguments to the variadic ... parameter were completely macro
> > >> expanded before considering whether the __VA_OPT__ ( pp-tokens ) would
> > >> expand to 'pp_tokens' or a single placemarker token. Evidently you are
> > >> saying that the correct interpretation with the __VA_OPT__ construct is
> > >> that the variadic ... arguments are not macro expanded before
> > >> consideration of the __VA_OPT__ construct processing . This seems to me
> > >> very odd because the arguments to the variadic ... parameter are always
> > >> completely macro expanded before being replaced by any __VA_ARGS__
> > >> parameter in the replacement list. I wonder why the C++ standard
> > >> committee decided to treat __VA_OPT__ differently from __VA_ARGS__ in
> > >> this regard ?
> > >
> > > I don't know.  I don't know if the GCC implementation is correct, either.
> >
> > Clang in its C++20 mode treats __VA_OPT__ as I thought it should be,
> > where the determination of whether __VA_OPT__ ( pp-tokens ) expands to a
> > placeholder token or pp-tokens is determined by whether the arguments
> > for the variadic data parameter ... are empty or not after the arguments
> > have been fully macro replaced. In other words clang expands to 1 in
> > both my examples above.
>
> #define T(a) #a
> T(NO_DATA)
>
> Expands to "NO_DATA", which means that it is:
>
> T(NO_DATA) -> #NO_DATA -> "NO_DATA"
>
> and not:
>
> T(NO_DATA) -> T() -> <error, no argument>
>
> Which explains why __VA_OPT__ behaves this way. According to godbolt
> T(NO_DATA) also expands to "NO_DATA", which would mean that difference
> between compilers boils down to checking if list is empty - gcc checks
> it before macro expansion, and clang after expansion?

Ugh, I just realized that this is what you wrote. Sorry for the noise.

-- 
Jędrzej Dudkiewicz

I really hate this damn machine, I wish that they would sell it.
It never does just what I want, but only what I tell it.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible __VA_OPT__ bug
  2019-10-31 16:43 Possible __VA_OPT__ bug Edward Diener
  2019-10-31 17:15 ` Segher Boessenkool
@ 2019-11-01 14:39 ` Edward Diener
  1 sibling, 0 replies; 8+ messages in thread
From: Edward Diener @ 2019-11-01 14:39 UTC (permalink / raw)
  To: gcc-help

On 10/31/2019 12:42 PM, Edward Diener wrote:
> Given:
> 
> #define NO_DATA
> #define TRY_VA_OPT(...)  __VA_OPT__ (0) 1
> 
> TRY_VA_OPT() -> expands to 1 as expected
> TRY_VA_OPT(NO_DATA) -> expands to 0 1 which is not expected
> 
> when compiled with gcc-9.2 with -std=c++2a.
> 
> I have not tested with gcc-8.1 on up at all C++ standard levels, as 
> __VA_OPT__ is supported there also, but I expect the same results will 
> occur.
> 
> I see no reason why both do not expand to 1. Is this a gcc bug ? If so, 
> I will report it to gcc. If not can anyone explain the second output ?
> 
> The command line parameters i used are:
> 
> -fvisibility-inlines-hidden -fPIC -m64 -pthread -O0 -fno-inline -Wall 
> -Wextra -pedantic -g -fvisibility=hidden -Wno-variadic-macros 
> -ftrack-macro-expansion=0 -std=c++2a

It is a gcc bug and I have reported it at 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92319. Thanks for 
everyone's comments !



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-11-01 14:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-31 16:43 Possible __VA_OPT__ bug Edward Diener
2019-10-31 17:15 ` Segher Boessenkool
2019-10-31 18:50   ` Edward Diener
2019-10-31 20:21     ` Segher Boessenkool
2019-10-31 20:28       ` Edward Diener
2019-10-31 21:28         ` Jędrzej Dudkiewicz
2019-10-31 21:31           ` Jędrzej Dudkiewicz
2019-11-01 14:39 ` Edward Diener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).