Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!mailrus!uunet!samsung!sdd.hp.com!ucsd!ames!sparkyfs!mckenney From: mckenney@sparkyfs.istc.sri.com (Paul Mckenney) Newsgroups: comp.lang.c++ Subject: Re: f***ing comments -- another pitfall to avoid Message-ID: <31914@sparkyfs.istc.sri.com> Date: 29 May 90 16:39:23 GMT References: <1504@trlluna.trl.oz> <69.UUL1.3#5109@pantor.UUCP> <54683@microsoft.UUCP> <0682@sheol.UUCP> <54781@microsoft.UUCP> <31891@sparkyfs.istc.sri.com> <219@taumet.COM> Reply-To: mckenney@perth.itstd.sri.com.UUCP (Paul E. McKenney) Organization: SRI International, Menlo Park, CA 94025 Lines: 88 In article <219@taumet.COM> steve@taumet.UUCP (Stephen Clamage) writes: >In article <31891@sparkyfs.istc.sri.com> mckenney@.itstd.sri.com (Paul E. McKenney) writes: >>Even if you have a preprocessor that knows about C++ comments, one must >>be careful... >>Consider the following: >>------------------------------------------------------------------------ >> #define commentmacro \ >> This is // (we interrupt this macro with a comment) \ >> a test >> commentmacro >>------------------------------------------------------------------------ >>Doing ``g++ -E'' yields: >> [ something unexpected ] >Well, we have an example of preprocessing that follows neither the >ANSI C standard nor the C++ Reference Manual (latest edition). According >to both, ANSI section 2.1.1.2 "Translation phases" and C++RM section 16.1 >"Phases of preprocessing", the escaped newline is deleted, and the >following line is concatenated. *After* that, tokenizing begins. >Thus the correct expansion for commentmacro is > This is >Your main point is well-taken: Do be careful with comments in macros, >at least until we get consistently correct behavior in C++ implementations. >The only safe thing is not to put comments in macros at all. >On the plus side (or ++ side), macros are not much needed in C++: >Instead of: #define MAX 10 >use: const int MAX = 10; >Instead of: #define foo(bar) expression >use: inline int foo(int bar) { return expression; } >The C++ alternatives are safer, in that they are properly scoped. I definitely agree that C++ features should be used in preference to preprocessor features where feasible. Unfortunately, my application would require templates in the case where I ran into this problem (and I am not absolutely positive that templates would be sufficient; I am not clear on the interaction between templates and inheritance). I sympathize with your interpretation of how commentmacro should be expanded, but I dislike the results, to say the least! The effect is that the first ``//'' comment encountered throws the rest of the macro definition away. If ``//'' comments are to be useful inside of macros, they should delete the text up to, but not including, the first occurance of either a newline or a backslash immediately preceding a newline. This does not really conflict with the ANSI C standard, since ANSI C does not have ``//'' comments. C++ would of course need to define the interaction explicitly -- the current smorgasborg of behaviors is no doubt in part due to the lack of explicit definition. Thanx, Paul PS. A (small) fragment of my big, ugly macro follows to motivate my desired behavior of comments in macro definitions. Processing ``//'' comments after deleting escaped newlines makes such comments almost useless in multiline macros. ------------------------------------------------------------------------ #define DEFINE_notifier(BASECLASS, MODIFIER) \ \ ... lots of stuff deleted ... \ \ class notifier_##BASECLASS##_##MODIFIER##_class; \ inline int notifier_##BASECLASS##_##MODIFIER##_class::add_recipient( \ notifiee_##BASECLASS##_##MODIFIER##_class &x \ ) \ \ { \ \ if (x.next != NULL) \ { \ \ // Added to the list twice, so die. \ \ return (0); \ } \ \ // Need mutual exclusion with del_recipient here for the \ // multiprocessor case. \ \ x.next = list; \ list = &x; \ return (1); \ } \ \ ... lots more stuff deleted ...