* `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( @ 2001-01-02 16:03 Francois Gouget 2001-01-03 4:36 ` Alexandre Oliva 2001-01-03 6:16 ` Neil Booth 0 siblings, 2 replies; 7+ messages in thread From: Francois Gouget @ 2001-01-02 16:03 UTC (permalink / raw) To: gcc; +Cc: jakub Hi, I'm having problems with the following piece of code (extracted from Wine's source): #define GetObject You_cannot_use_GetObject_in_this_context #define ICOM_FN(xfn) fn ## xfn #define DECLARE1(xfn) void ICOM_FN(xfn) (void); #define DECLARE2(xfn) void ICOM_FN(##xfn) (void); ICOM_FN(GetObject) DECLARE1(GetObject) DECLARE2(GetObject) I expect to get (blank and not relevant lines removed): fnGetObject void fnYou_cannot_use_GetObject_in_this_context (void); void fnGetObject (void); But I've had problems with recent versions of gcc. One version (20001002) produced: test.c:6:38: warning: nothing can be pasted after this token fnGetObject void fnYou_cannot_use_GetObject_in_this_context (void); void fnYou_cannot_use_GetObject_in_this_context (void); But more recent versions work again so this seems to be fixed. But I still get the following warning: test.c:11:1: warning: pasting "(" and "GetObject" does not give a valid preprocessing token Is this use of '##' still going to be supported in the future? Is it possible to not issue a warning in this situation (I know about the macro vararg problem). Reading the Cpp documentation I see: -- http://gcc.gnu.org/onlinedocs/cpp_1.html#SEC46 Attempting to paste two tokens which together do not form a valid preprocessing token The preprocessor currently warns about this and outputs the two tokens adjacently, which is probably the behavior the programmer intends. It may not work in future, though. Most of the time, when you get this warning, you will find that `##' is being used superstitiously, to guard against whitespace appearing between two tokens. It is almost always safe to delete the `##'. -- But this does not cover what I do which is to use the concatenation operator to avoid the argument prescan described in 'Separate Expansion of Macro Arguments' -- http://gcc.gnu.org/onlinedocs/cpp_toc.html#SEC29 We have explained that the expansion of a macro, including the substituted arguments, is re-scanned for macro calls to be expanded. What really happens is more subtle: first each argument is scanned separately for macro calls. Then the resulting tokens are substituted into the macro body to produce the macro expansion, and the macro expansion is scanned again for macros to expand. -- -- http://gcc.gnu.org/onlinedocs/cpp_toc.html#SEC29 The prescan is not done when an argument is stringified or concatenated. -- Since this is unrelated to the macro vararg issue it would be nice if there was a way to avoid the warning in this context (otherwise we'll have to change the code and duplicate 30+ macros :-( ). PS: I apologize if this is the wrong mailing list. Would gcc-bugs be more appropriate (seems like it is more gnats oriented)? jakub, Bernhard Rosenkraenzer told me you would be interested in being cc-ed. -- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ RFC 2549: ftp://ftp.isi.edu/in-notes/rfc2549.txt IP over Avian Carriers with Quality of Service ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( 2001-01-02 16:03 `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( Francois Gouget @ 2001-01-03 4:36 ` Alexandre Oliva 2001-01-03 10:01 ` Francois Gouget 2001-01-03 6:16 ` Neil Booth 1 sibling, 1 reply; 7+ messages in thread From: Alexandre Oliva @ 2001-01-03 4:36 UTC (permalink / raw) To: Francois Gouget; +Cc: gcc, jakub On Jan 2, 2001, Francois Gouget <fgouget@free.fr> wrote: > #define DECLARE2(xfn) void ICOM_FN(##xfn) (void); This doesn't produce a valid token after token pasting. CVS GCC is correct in warning about it. I think an ISO C-compliant solution would be to define DECLARE2 so that it takes an additional empty argument, and use token pasting to paste this empty argument to the symbol name. #define DECLARE2(xfn,empty) void ICOM_FN(empty ## xfn) (void); DECLARE2(GetObject,) The alternative I see to preserve the interface of DECLARE2 is to not use ICOM_FN, but instead concatenate fn with xfn explicitly. I don't know if any of these are viable alternatives for Wine. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{cygnus.com, redhat.com} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist *Please* write to mailing lists, not to me ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( 2001-01-03 4:36 ` Alexandre Oliva @ 2001-01-03 10:01 ` Francois Gouget 2001-01-03 10:33 ` Francois Gouget 0 siblings, 1 reply; 7+ messages in thread From: Francois Gouget @ 2001-01-03 10:01 UTC (permalink / raw) To: Alexandre Oliva; +Cc: gcc, jakub On 3 Jan 2001, Alexandre Oliva wrote: > On Jan 2, 2001, Francois Gouget <fgouget@free.fr> wrote: > > > #define DECLARE2(xfn) void ICOM_FN(##xfn) (void); > > This doesn't produce a valid token after token pasting. CVS GCC is > correct in warning about it. > > I think an ISO C-compliant solution would be to define DECLARE2 so > that it takes an additional empty argument, and use token pasting to > paste this empty argument to the symbol name. > > #define DECLARE2(xfn,empty) void ICOM_FN(empty ## xfn) (void); > > DECLARE2(GetObject,) Brilliant! I didn't think about that, I like it. > The alternative I see to preserve the interface of DECLARE2 is to not > use ICOM_FN, but instead concatenate fn with xfn explicitly. The problem with this solution is that, I should have said so, we change the definition of ICOM_FN depending on another macro. So ICOM_FN does not always prepend fn. So we would have to duplicate all the macros that use ICOM_FN. Feasible but ugly. But I like your first suggestion. I'll implement it, that way we'll avoid all problems. Thanks. -- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ Good judgment comes from experience, and experience comes from bad judgment -- Barry LePatner ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( 2001-01-03 10:01 ` Francois Gouget @ 2001-01-03 10:33 ` Francois Gouget 2001-01-03 11:15 ` Alexandre Oliva 0 siblings, 1 reply; 7+ messages in thread From: Francois Gouget @ 2001-01-03 10:33 UTC (permalink / raw) To: Alexandre Oliva; +Cc: gcc, jakub On Wed, 3 Jan 2001, Francois Gouget wrote: > On 3 Jan 2001, Alexandre Oliva wrote: > > > On Jan 2, 2001, Francois Gouget <fgouget@free.fr> wrote: > > > > > #define DECLARE2(xfn) void ICOM_FN(##xfn) (void); > > > > This doesn't produce a valid token after token pasting. CVS GCC is > > correct in warning about it. > > > > I think an ISO C-compliant solution would be to define DECLARE2 so > > that it takes an additional empty argument, and use token pasting to > > paste this empty argument to the symbol name. > > > > #define DECLARE2(xfn,empty) void ICOM_FN(empty ## xfn) (void); > > > > DECLARE2(GetObject,) > > Brilliant! > I didn't think about that, I like it. Oups. I talked too fast. It's still brilliant and I didn't think of it. But I got confused and thought I could just modify ICOM_FN when in fact it's DECLARE I have to modify, i.e. in Wine ICOM_METHOD. These macros are used to declare each COM method (about 1500 of them so far). Of course, I'd rather not add commas all other the place. Is there any other way I could avoid the prescan? > > The alternative I see to preserve the interface of DECLARE2 is to not > > use ICOM_FN, but instead concatenate fn with xfn explicitly. > > The problem with this solution is that, I should have said so, we > change the definition of ICOM_FN depending on another macro. So ICOM_FN > does not always prepend fn. So we would have to duplicate all the macros > that use ICOM_FN. Feasible but ugly. Well, less of a problem than modifying the 1500 uses of the ICOM_METHOD macros. It means instead I'l duplicate the definition of (only) 33 macros :-( Currently it looks like so: #ifndef ICOM_CINTERFACE #define ICOM_METHOD(ret,xfn) \ public: virtual ret CALLBACK (xfn)(void) = 0; #define ICOM_METHOD1(ret,xfn,ta,na) \ public: virtual ret CALLBACK (xfn)(ta a) = 0; ... #define ICOM_FN(xfn) xfn #else /* ICOM_CINTERFACE */ #ifdef __WINE__ #define ICOM_FN(xfn) fn##xfn #else #define ICOM_FN(xfn) xfn #endif #define ICOM_METHOD(ret,xfn) \ ret CALLBACK (*ICOM_FN(##xfn))(ICOM_INTERFACE* me); #define ICOM_METHOD1(ret,xfn,ta,na) \ ret CALLBACK (*ICOM_FN(##xfn))(ICOM_INTERFACE* me,ta a); ... #endif /* ICOM_CINTERFACE `*/ #define ICOM_CALL(xfn, p) ICOM_VTBL(p)->ICOM_FN(##xfn)(p) ... -- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ "Only wimps use tape backup: _real_ men just upload their important stuff on ftp, and let the rest of the world mirror it ;)" -- Linus Torvalds ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( 2001-01-03 10:33 ` Francois Gouget @ 2001-01-03 11:15 ` Alexandre Oliva 2001-01-03 15:52 ` Francois Gouget 0 siblings, 1 reply; 7+ messages in thread From: Alexandre Oliva @ 2001-01-03 11:15 UTC (permalink / raw) To: Francois Gouget; +Cc: gcc, jakub On Jan 3, 2001, Francois Gouget <fgouget@free.fr> wrote: > Is there any other way I could avoid the prescan? Neil suggested using a varargs macro argument, introduced in C99 and supported by CVS GCC. #define DECLARE2(xfn,...) void ICOM_FN(xfn ## __VA_ARGS__) (void) One solution that appears to work with old and new version of GCC is: #define DECLARE2(xfn,rest...) void ICOM_FN(xfn ## rest) (void) But the use of the ISO C99-compliant solution is encouraged. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{cygnus.com, redhat.com} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist *Please* write to mailing lists, not to me ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( 2001-01-03 11:15 ` Alexandre Oliva @ 2001-01-03 15:52 ` Francois Gouget 0 siblings, 0 replies; 7+ messages in thread From: Francois Gouget @ 2001-01-03 15:52 UTC (permalink / raw) To: Alexandre Oliva; +Cc: gcc On 3 Jan 2001, Alexandre Oliva wrote: > On Jan 3, 2001, Francois Gouget <fgouget@free.fr> wrote: > > > Is there any other way I could avoid the prescan? > > Neil suggested using a varargs macro argument, introduced in C99 and > supported by CVS GCC. > > #define DECLARE2(xfn,...) void ICOM_FN(xfn ## __VA_ARGS__) (void) > > One solution that appears to work with old and new version of GCC is: > > #define DECLARE2(xfn,rest...) void ICOM_FN(xfn ## rest) (void) > > But the use of the ISO C99-compliant solution is encouraged. Ah! I did not think about it that way. That works. I'm not overly enthusisatic about using vararg macros though. The problem is it's hard to make them work across compilers (not that Wine's code is extremely protable to start with but we try still). Oh well, we'll duplicate the definitions. It's not that bad. Thanks a lot for your help! -- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ Avoid the Gates of Hell - use Linux. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( 2001-01-02 16:03 `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( Francois Gouget 2001-01-03 4:36 ` Alexandre Oliva @ 2001-01-03 6:16 ` Neil Booth 1 sibling, 0 replies; 7+ messages in thread From: Neil Booth @ 2001-01-03 6:16 UTC (permalink / raw) To: Francois Gouget; +Cc: gcc, jakub Francois Gouget wrote:- > #define DECLARE2(xfn) void ICOM_FN(##xfn) (void); > > I expect to get (blank and not relevant lines removed): > > void fnGetObject (void); > > But more recent versions work again so this seems to be fixed. But I > still get the following warning: > test.c:11:1: warning: pasting "(" and "GetObject" does not give a valid > preprocessing token > > Is this use of '##' still going to be supported in the future? No. GCC in future versions may even upgrade this warning to a hard error. > Is it possible to not issue a warning in this situation (I know about > the macro vararg problem). No. There may be other ways to achieve what you want; e.g. having an extra empty argument and pasting that, or making it a varargs argument if you don't want to have to enter the comma in invocations. Neil. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2001-01-03 15:52 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2001-01-02 16:03 `Cpp: 'ICOM_FN(##xfn)' generates a warning :-( Francois Gouget 2001-01-03 4:36 ` Alexandre Oliva 2001-01-03 10:01 ` Francois Gouget 2001-01-03 10:33 ` Francois Gouget 2001-01-03 11:15 ` Alexandre Oliva 2001-01-03 15:52 ` Francois Gouget 2001-01-03 6:16 ` Neil Booth
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).