Hi,
Am 9. Juli 2025 20:15:57 MESZ schrieb Corentin via Liaison <liaison@lists.isocpp.org>:
> On Mon, Jul 7, 2025 at 7:38 PM Jens Maurer <jens.maurer@gmx.net> wrote:
>
> >
> >
> > On 07.07.25 17:41, Corentin via Core wrote:
> > > Hey folks,
> > >
> > > [[foo(#)]] is a valid attribute in C, but invalid in C++, as # is
> > considered a token in C and a preprocessing-operator in C++
> > > (The grammar of attributes expects tokens in both languages)
> > >
> > > Is this divergence intended? It does not seem desirable.
> > >
> > > Note that there is implementation divergence amongst C++ compilers here,
> > Clang accepts in all language modes, GCC rejects in all language modes
> > https://godbolt.org/z/Wj5fqdd1x <https://godbolt.org/z/Wj5fqdd1x>
> >
> > Looks like ## should have the same divergence.
> >
>
> yes, the same question applies to all of #, ##, %:, %:%:
Actually to all preprocessor tokens, that have no equivalent
in translation phase 7. these are probably a lot more than the ones
listed.
In addition to # and ##, in the basic source character set there's also ` @ $ \ which satisfy the "single character that's not the start of another preprocessing-token" rule. EDG rejects all of those, GCC and MSVC reject all but $, clang accepts all.
Then there are pp-numbers that don't correspond to tokens, such as 0xhello. GCC and Clang accept that in an attribute, EDG and MSVC reject.
I think that also gives a pretty strong justification for allowing arbitrary pp-numbers as attribute arguments: these come up for version numbers. And indeed Clang has an attribute, in use in production, that accepts a pp-number that's not a token. For example:
[[clang::availability(linux, introduced=2.6.16)]]
int faccessat(int dirfd, const char *pathname, int mode, int flags);
This attribute is accepted by Clang and successfully ignored by MSVC, but GCC and EDG fail to ignore it and instead diagnose the pp-number having too many decimal points.
Should we add a new kind of token for "miscellaneous preprocessing-token that is not otherwise a token", that's only valid within attributes?