On Fri, Aug 16, 2024 at 04:05:52PM +0000, Joseph Myers wrote: > On Fri, 16 Aug 2024, Jakub Jelinek wrote: > > > > Apart from any consequences for arguments of prefix/suffix/is_empty > > > (where > > > there is a plausible argument that the argument should get expanded at > > > some point and that the current wording is undesirable for usability), > > > this would also mean that e.g. > > > > > > #define LIMIT limit > > > #embed "file" LIMIT(1) > > > > > > isn't valid because LIMIT doesn't get expanded (the syntax for > > > non-expanded #embed is met, with an unknown parameter LIMIT), while > > > > > > #define limit ! > > > #embed "file" limit(1) > > > > > > *is* valid, because limit doesn't get expanded (which may be convenient > > > for usability - it means headers don't need to use __limit__ if using > > > #embed, even if files including the header might have defined limit as a > > > macro). > > > > Is there an agreement on that? > > I think it's understood to be what the words mean (apart from the recent > discussion, also noted in February 2022 discussion - e.g. > <https://www.open-std.org/jtc1/sc22/wg14/21635>). Whether it's desirable > is another matter. Apart from likely wanting to be able to use macros > within the prefix/suffix/if_empty arguments, it would also seem fairly > reasonable to want to have a macro expanding to such parameters used with > more than one directive. > > #define PARAMS prefix(X) suffix(Y) > > #embed "a" PARAMS > > #embed "b" PARAMS > > without needing to arrange for the directive not to look like one of the > other forms before macro expansion. > > I've added this to my list of issues to file once we have an issue > tracking system for the C standard in operation.
Ok. So for now, should I work on a patch variant which tries to follow what is in C23 right now? I.e. most likely set pfile->state.prevent_expansion = 1; initially, keep checking the tokens just for the basic syntax match (header token or string literal, followed by check for pp-parameter matches if any until end of line, based on that decide and push all the read tokens back to lookaside? Still, as I wrote, not really sure if it goes with the pfile->state.prevent_expansion = 1 decision when temporarily switching that off for the limit argument real parsing when the closing ) (i.e. non-balanced) comes from a macro, and whether to ignore the macro expansion of prefix/suffix/if_empty altogether, or push those expanded when actually using them (and if so, again, what to do with unbalanced case; maybe in that case it would be desirable and would allow to insert unbalanced {,(,[,],),} to the token stream). > My concern here is more with the use of the fields in cpp_options, than > with the initialization of that from lang_flags. Maybe that large > lang_defaults table isn't the optimal way of initializing all those > cpp_options fields (although initializing CPP_OPTION (pfile, > embed_directive) from l->warning_directive would also be awkward; the > question is more whether computing the cpp_options fields with logic like > "C from version X onwards, C++ from version Y onwards" would be an > improvement on a table taking 147 columns). Ok, will change it. And think how to improve the table next. Indeed, having some macro for this option is C >= n && C++ >= m, whether GNU only or standard etc. would be nice. Right now it is 28x23 bit matrix. One possibility would be /* u e w b d 8 l a t x u i i c v s s i r d r x i d u r d n g t h a c z f n e u c c n x c d s i l l l c s r l o o d l d d l f 9 + u i 1 i t g i i i s e i i p p f i e i i a 9 + m d 1 d d r t t t t p g t t e p t f r m l */ { /* GNUC89 */ { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0 }, /* GNUC99 */ { 1,0,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0 }, /* GNUC11 */ { 1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0 }, /* GNUC17 */ { 1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0 }, /* GNUC23 */ { 1,0,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,1,0,1 }, /* GNUC2Y */ { 1,0,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,1,0,1 }, /* STDC89 */ { 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 }, /* STDC94 */ { 0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 }, /* STDC99 */ { 1,0,1,1,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 }, /* STDC11 */ { 1,0,1,1,1,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0 }, /* STDC17 */ { 1,0,1,1,1,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0 }, /* STDC23 */ { 1,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,1 }, /* STDC2Y */ { 1,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,1 }, /* GNUCXX */ { 0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1 }, /* CXX98 */ { 0,1,0,1,0,1,1,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1 }, /* GNUCXX11 */ { 1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1 }, /* CXX11 */ { 1,1,0,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,0,0,0,1 }, /* GNUCXX14 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,1 }, /* CXX14 */ { 1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,1 }, /* GNUCXX17 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,1 }, /* CXX17 */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,0,0,0,1 }, /* GNUCXX20 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,1 }, /* CXX20 */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,1 }, /* GNUCXX23 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1 }, /* CXX23 */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1 }, /* GNUCXX26 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1 }, /* CXX26 */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1 }, /* ASM */ { 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }; Jakub