schweitz@lexvmc.iinus1.ibm.com ("Eric Schweitz") (02/16/91)
From: schweitz@lexvmc.iinus1.ibm.com Date: 15 February 1991, 10:41:22 EST I have a question concerning the preprocessor. Namely, what behavior SHOULD be expected from the following: #define one val1,val2 #define two(arg1,arg2) arg1+arg2 .... two (one) // ? Should this evaluate to: a) val1+val2 -or- b) val1,val2+ Please excuse me if this is a neophyte question. Also, is this behavior different of the same for C and C++? Thanks, Schweitz schweitz@lexvmc.iinus1.ibm.com
crawford@scri.fsu.edu (Lee Crawford) (02/17/91)
Well, its a simple consideration of the preprocessors replacement ordering. You asked: | What behavior SHOULD be expected from the following: | | #define one val1,val2 | #define two(arg1,arg2) arg1+arg2 | | .... | | two(one) I guess I'll give answering your question a shot: I think what you have to understand is how the C/C++ preprocessor works, for it is the preprocessing phase of compilation that is causing the effects that you find strange. The initial actions of the preprocessor are to break up the text of any source code into a stream of tokens. As it breaks off these tokens it scans then for macro calls. (A macro constant just has not parrenthesization) Thus, for either of the following two code segments: #define one val1,val2 #define two(arg1,arg2) arg1+arg2 or #define two(arg1,arg2) arg1+arg2 #define on val1,val2. You notice that the first recognized token of the program text: two(one) would be the string "two". Thus regardless of the ordering of the definitions or whatnot, the preprocesser first turns its attentions to a replacement of the macro "two". Thus: two(one) becomes one+ and you will likely find yourself with an error message mentioning that the required number of arguments was not present. When macro replacement occurs during preprocessing, after a single replacement the preprocessor resumes token scanning at the beginning of the previous expansion. Thus the preprocessor is now trying to figure out what to do with: one+ It then finds the token "one" and replaces it with "val1,val2". And one+ becomes val1,val2+. I hope this has all made sense. If you wanted val1+val2 as the expansion of your macro invocation then you will have to sort out a different way of doing so. -------------------- Cut here --------------------------------------- Lee Crawford Florida State University Department of Physics crawford@fsulcd.physics.fsu.edu (INTER/ARPA-NET) fsulcd::crawford (DECnet) (904) 644 2334 (LipNET) -------------------------------------------------------------------
zvs@bby.oz.au (Zev Sero) (02/19/91)
Eric = schweitz@lexvmc.iinus1.ibm.com ("Eric Schweitz") Eric> I have a question concerning the preprocessor. Namely, what behavior Eric> SHOULD be expected from the following: Eric> #define one val1,val2 Eric> #define two(arg1,arg2) arg1+arg2 Eric> .... Eric> two (one) // ? Eric> Should this evaluate to: Eric> a) val1+val2 Eric> -or- Eric> b) val1,val2+ The correct answer is b. I quote from H&S 2, page 33: Once a macro call has been expanded, the scan for macro calls resumes at the beginning of the expansion; this is so that names of macros may be recognized within the expansion for the purpose of further macro replacement...Macro replacement is also not performed within the actual argument token strings of a complex macro call at the time the macro call is being scanned. Macro names are recognised within actual argument token strings only during the rescanning of the expansion. Therefore your macro is expanded in the following steps: two (one) --> one+ At this point one is not recognised as a macro. Then the expression is rescanned: one+ --> val1,val2+ -- Zev Sero - zvs@bby.oz.au This I say unto you, be not sexist pigs. - The prophetess, Morgori Oestrydingh (S.Tepper)