bpm@psuecl.bitnet (Brian Moquin) (12/03/89)
A student in my C class asked me an interesting question: can you have conditional compilation directives embedded within '#define' macros? The answer is no. The student pointed out that this then severely limits the macro capabilities of C. He said that in assembler (MASM, I'm sure), he can write macros which contain arguments that determine how the macros get expanded. I had trouble coming up with a good analogous example in C, but here's one to think about: #define cast(flag,x) #if flag=='I' \ ((int)(x)) \ #elif flag=='F' \ ((float)(x)) \ #endif This is not legal C, but if it were I think it would enhance the power of macro expansions significantly. Thoughts?
poser@csli.Stanford.EDU (Bill Poser) (12/04/89)
A simple macro processor, like the one we have, is a Good Thing. I am not so sure that a more powerful macro processor along the same lines would be. For one thing, the syntax of macro languages is nasty, and not conducive to good programming practice, and when one writes complex macros, in effect one is making use of a meta-programming language. So my gut reaction to proposals for non-trivial extensions to cpp is generally one of the following, depending on the case at hand: (a) The problem really calls for make(1); (b) The problem is better handled by means of preprocessing by means of an independent language, e.g. AWK or ICON; (c) The user really should be using a language other than C. This is isn't to say that one of these is always the solution or that every extension to cpp is a bad idea, but it does seem to me that complex macro expansions are fragile, hard to document, and easy to abuse.
bill@twwells.com (T. William Wells) (12/04/89)
In article <69517@psuecl.bitnet> bpm@psuecl.bitnet (Brian Moquin) writes:
: A student in my C class asked me an interesting question: can you have
: conditional compilation directives embedded within '#define' macros?
: The answer is no. The student pointed out that this then
: severely limits the macro capabilities of C. He said that in assembler
: (MASM, I'm sure), he can write macros which contain arguments that
: determine how the macros get expanded. I had trouble coming up with
: a good analogous example in C, but here's one to think about:
: #define cast(flag,x) #if flag=='I' \
: ((int)(x)) \
: #elif flag=='F' \
: ((float)(x)) \
: #endif
: This is not legal C, but if it were I think it would enhance the power
: of macro expansions significantly. Thoughts?
This particular one can be dealt with in ANSI C, I think.
Something like:
#define cast_F(x) ((float)(x))
#define cast_I(x) ((int)(x))
#define cast(flag,x) cast_##flag((x))
---
Bill { uunet | novavax | ankh | sunvice } !twwells!bill
bill@twwells.com
richard@calvin.EE.CORNELL.EDU (Richard Brittain) (12/04/89)
In article <11250@csli.Stanford.EDU> poser@csli.stanford.edu (Bill Poser) writes: > >A simple macro processor, like the one we have, is a Good Thing. >I am not so sure that a more powerful macro processor along the >same lines would be. For one thing, the syntax of macro languages >is nasty, and not conducive to good programming practice, and when one >writes complex macros, in effect one is making use of a meta-programming >language. So my gut reaction to proposals for non-trivial extensions to >cpp is generally one of the following, depending on the case at hand: ..... examples deleted Another problem with using complex macros, particularly if they affect function declarations or variable/array declarations, is that most source code analysis tools, pretty printers etc. will break. Running them on the output of cpp doesn't cut it if part of the output involves line numbers into the source file. Richard Brittain, School of Elect. Eng., Upson Hall Cornell University, Ithaca, NY 14853 ARPA: richard@calvin.spp.cornell.edu UUCP: {uunet,uw-beaver,rochester,cmcl2}!cornell!calvin!richard
henry@utzoo.uucp (Henry Spencer) (12/04/89)
In article <69517@psuecl.bitnet> bpm@psuecl.bitnet (Brian Moquin) writes: >A student in my C class asked me an interesting question: can you have >conditional compilation directives embedded within '#define' macros? >The answer is no. The student pointed out that this then >severely limits the macro capabilities of C... He is correct. C is not intended to be the answer to all the world's problems. In particular, the C preprocessor is not intended to be an all-singing-all-dancing Turing-capable macro language. As Dennis put it: "If you want PL/I, you know where to find it." -- Mars can wait: we've barely | Henry Spencer at U of Toronto Zoology started exploring the Moon. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
lmiller@aerospace.aero.org (Lawrence H. Miller) (12/05/89)
In article <69517@psuecl.bitnet> bpm@psuecl.bitnet (Brian Moquin) writes: That he thinks macros like this would be useful: > #define cast(flag,x) #if flag=='I' \ > ((int)(x)) \ > #elif flag=='F' \ > ((float)(x)) \ > #endif >This is not legal C, but if it were I think it would enhance the power >of macro expansions significantly. Thoughts? But for each such example, you can easily write a macro that is legal. Why not just have your macro do what you really want, which is casting an expression to a type: #define cast(type,x) ((type)(x)) Larry Miller
erc@khijol.UUCP (Edwin R. Carp) (12/05/89)
In article <69517@psuecl.bitnet> bpm@psuecl.bitnet (Brian Moquin) writes: > #define cast(flag,x) #if flag=='I' \ > ((int)(x)) \ > #elif flag=='F' \ > ((float)(x)) \ > #endif Couldn't you do the same thing with: #if flag=='I' #define cast(flag,x) ((int)(x)) #elif flag=='F' #define cast(flag,x) ((flaot)(x)) #endif ----------------------------------- cut here ----------------------------------- Ed Carp N7EKG/5 (28.3-28.5) erc@puzzle!khijol Austin, Tx; (home) (512) 445-2044 Snail Mail: 1800 E. Stassney #1205 Austin, Tx 78744
oz@yunexus.UUCP (Ozan Yigit) (12/05/89)
In article <11250@csli.Stanford.EDU> poser@csli.stanford.edu (Bill Poser) writes: >A simple macro processor, like the one we have, is a Good Thing. >I am not so sure that a more powerful macro processor along the >same lines would be. I do not know what "more powerfull macro processor" means. How powerful is powerful ?? [This is a trick question :-)] > For one thing, the syntax of macro languages >is nasty, and not conducive to good programming practice, and when one >writes complex macros, in effect one is making use of a meta-programming >language. Bad syntax is a design problem, not a generic problem of macro processors. As for "conducive to good programming practice", say, what was that language in which we "obfuscate" ?? Perl ?? Naah, but close !! :-) The difference between a meta programming language as opposed to a "real" one is a matter of abstraction, if done properly. >So my gut reaction to proposals for non-trivial extensions to >cpp ... I think CPP is beyond hope for future extensions. One could, however build more interesting macro processors that can resemble CPP for the most part, or perhaps not resemble it at all... There has been some subset cpps in the past, and I have seen supersets as well. Bless that "little languages" approach. oz -- There are two kinds of fool. Internet: oz@nexus.yorku.ca One says, "This is old, and therefore good" Uucp: uunet!utai!yunexus!oz And one says "This is new, and therefore Better" Bitnet: oz@[yulibra|yuyetti] John Brunner (The Shockwave Rider) Phonet: +1 416 736-5257x3976
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/05/89)
In article <69517@psuecl.bitnet> bpm@psuecl.bitnet (Brian Moquin) writes: >This is not legal C, but if it were I think it would enhance the power >of macro expansions significantly. Thoughts? My thought is that it's irrelevant. C's preprocessing facilities were never meant to serve as a general macro processing language.
) (12/06/89)
In article <69517@psuecl.bitnet> bpm@psuecl.bitnet (Brian Moquin) writes: >A student in my C class asked me an interesting question: can you have >conditional compilation directives embedded within '#define' macros? >The answer is no. The student pointed out that this then >severely limits the macro capabilities of C. He said that in assembler >(MASM, I'm sure), he can write macros which contain arguments that >determine how the macros get expanded. I had trouble coming up with >a good analogous example in C, but here's one to think about: > #define cast(flag,x) #if flag=='I' \ > ((int)(x)) \ > #elif flag=='F' \ > ((float)(x)) \ > #endif In (Reiser) cpp you can accomplish this sort of thing with token pasting and a few additional macros: #define _CAT(a,b) a/**/b #define cast(flag,x) _CAT(_CAST,flag)(x) #define _CASTI(x) ((int) (x)) #define _CASTF(x) ((float) (x)) cast(I, foo) cast(F, bar) -- David DiGiacomo, Sun Microsystems, Mt. View, CA sun!david david@eng.sun.com
Tim_N_Roberts@cup.portal.com (12/06/89)
Re: Discussion of C Pre-processor limitations: Remember that most (all?) Unix implementations include M4, which is a rather powerful macro expansion facility. It would be perfectly feasible to have your makefile call M4 before invoking cc. TNR@cup.portal.com | I Survived The ...!sun!portal!cup.portal.com!tnr | Great Quake of '89.
peter@ficc.uu.net (Peter da Silva) (12/07/89)
In article <24736@cup.portal.com> Tim_N_Roberts@cup.portal.com writes: > Remember that most (all?) Unix implementations include M4, which is > a rather powerful macro expansion facility. It would be perfectly > feasible to have your makefile call M4 before invoking cc. C does not imply UNIX. It's fun to bitch about MS-DOS specific junk floating around in here, but assuming that UNIX == C is worse. -- `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>. 'U` Also <peter@ficc.lonestar.org> or <peter@sugar.lonestar.org>. "If you want PL/I, you know where to find it." -- Dennis
tps@chem.ucsd.edu (Tom Stockfisch) (12/07/89)
In article <62664@aerospace.AERO.ORG> lmiller@batcomputer.UUCP (Lawrence H. Miller) writes: >In article <69517@psuecl.bitnet> bpm@psuecl.bitnet (Brian Moquin) writes: >> #define cast(flag,x) #if flag=='I' \ >> ((int)(x)) \ >> #elif flag=='F' \ >> ((float)(x)) \ >> #endif >>This is not legal C, but if it were I think it would enhance the power > >But for each such example, you can easily write a macro that >is legal. It is not always possible to write a legal macro, at least not easily. For instance, suppose we want to define "nearest neighbors" of a lattice with periodic boundary conditions (neighbors of the edges wrap around to the other edge), and we want addressing to be very fast. int lat[DIM*DIM]; # define XNeighbor(i) # if (i)%DIM == DIM-1 ( (i) - DIM + 1 ) # else ( (i) + 1 ) # define YNeighbor(i) # if (i) >= DIM*(DIM - 1) ( (i) + DIM ) # else ( (i) - DIM*(DIM - 1) ) ... switch (s) { case 0: DoSomething( lat[XNeighbor(s)] + lat[YNeighbor(s)] ); break; case 1: DoSomething( lat[XNeighbor(s)] + lat[YNeighbor(s)] ); break; ... case DIM*DIM-1: DoSomething( lat[XNeighbor(s)] + lat[YNeighbor(s)] ); break; default: assert(0); } When I have had to do this, I simply eliminate the "#" before the "if" and the "else", and depend on the compiler to optimize out all of the branches that can't be reached (in this case, half of them), and ignore the deluge of "constant in conditional context" warnings from lint. M4 is usually of little or no help because too many C things are used in the constant arithmetic. -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu
scs@itivax.iti.org (Steve Simmons) (12/08/89)
In article <69517@psuecl.bitnet> bpm@psuecl.bitnet (Brian Moquin) writes: >This is not legal C, but if it were I think it would enhance the power >of macro expansions significantly. Thoughts? Keep complex macro processing in macro processing languages, leave a well-defined standard (well....) alone. See m4. Shucks, if it were up to me there wouldn't be a cpp at all. -- Steve Simmons scs@iti.org Industrial Technology Institute '"You're not a big name on Usenet until someone puts you in their .sig file." -- Anonymous'