From -4877877541702421441
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: fc772,a175c482da34ebf8
X-Google-Attributes: gidfc772,public
X-Google-Thread: f78e5,765aa557d15ef5ba
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 2003-05-10 11:39:51 PST
Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news.uchicago.edu!news-hog.berkeley.edu!ucberkeley!enews.sgi.com!news.xtra.co.nz!news.mel.connect.com.au!news.unimelb.edu.au!bounce-back
From: "Paul Mensonides" <leavings@attbi.com>
Newsgroups: comp.std.c++,comp.lang.c++.moderated
Subject: Re: Preprocessor evolution
Date: 10 May 03 18:39:03 GMT
Organization: AT&T Broadband
Lines: 123
Approved: Fergus Henderson <fjh@cs.mu.oz.au>
Message-ID: <vaVua.534065$OV.502037@rwcrnsc54>
References: <652361f.0304032218.6b7a67e4@posting.google.com>
 <MXoja.40640$JI.9909097@twister.neo.rr.com>
 <3e8f6897.709822312@News.CIS.DFN.DE>
 <d6651fb6.0304070135.2222325e@posting.google.com>
 <3e920e1f.883270640@News.CIS.DFN.DE>
 <Xns9367DD6DE352Bconley141osuedu@206.127.4.10>
 <Xns936896E7430E9conley141osuedu@65.24.2.11>
 <ZP_sa.724059$F1.93803@sccrnsc04>
 <Xns936A859ECFE62conley141osuedu@65.24.2.11>
 <WuAta.745871$L1.211469@sccrnsc02>
 <Xns9375F374D954Econley141osuedu@65.24.2.11>
NNTP-Posting-Host: mundook.cs.mu.oz.au
X-Trace: ariel.ucs.unimelb.edu.au 1052591989 17112 128.250.34.60 (10 May 2003 18:39:49 GMT)
X-Complaints-To: news@news.unimelb.edu.au
NNTP-Posting-Date: 10 May 2003 18:39:49 GMT
X-Original-Date: 9 May 2003 22:48:57 -0400
Delivered-To: std-c++@ucar.edu
X-Submission-Address: c++-submit@netlab.cs.rpi.edu
X-Auth: PGPMoose V1.1 PGP comp.lang.c++.moderated
	iQBVAwUAPrxojEHMCo9UcraBAQHRqAH/Xq6IVWzrnE2JllGIumh+stD/J3jdMmyI
	W1bjxjGDa0oa05tZROYmtwafMrvcQhKC+kDSNZgZ0GxDnoLdzEcB2g==
	=9SKF
X-Approved-For-Group: kuehl@inf.uni-konstanz.de comp.lang.c++.moderated
X-Scanned-By: MIMEDefang 2.28
X-Spam-Status: No, hits=-8.5 required=5.0
	tests=INVALID_MSGID,NOSPAM_INC,QUOTED_EMAIL_TEXT,REFERENCES,
	      SPAM_PHRASE_02_03
	version=2.41
X-Auth: PGPMoose V1.1 PGP comp.std.c++
	iQBFAgUAPr1HSuEDnX0m9pzZAQECdQGAgzrCzWpXUzeX/4jhUN6wcad5uHjrZcC4
	/SFKDcy8zMOkTiZc6T0ge8OEqkOnZOFr
	=nm8C
Xref: archiver1.google.com comp.std.c++:19333 comp.lang.c++.moderated:65792

Mike Conley wrote:
> Paul Mensonides <leavings@attbi.com> wrote in
> news:WuAta.745871$L1.211469@sccrnsc02:
>
>> I can count up to 2^512 arguments with my current "strict"
>> implementation of the Boost pp-lib.  Granted, it isn't the limit that
>> matters.  Rather, it that you have to count them at all. :)
>
> I thought the limit was much smaller.  Guess I'll have to take a
> closer look at it.  But, as you say, it's the need to count, not the
> limit, that's bothersome.

The limit is much small in the Boost pp-lib.  That is because I cannot get away
with a great many things because of buggy preprocessors.  The "strict" version
of the library is an entirely separate implementation that I haven't released
yet (though it should be soon).  This version of the library abstracts recursion
into a single set of macros.  This makes macro algorithmic, so writing the
entire BOOST_PP_REPEAT or BOOST_PP_WHILE construct only takes about 3-4 macros
each.  Likewise, it allows you to create exponential loops, etc., that have a
massively higher theoretical limit--such as 2^512.  I should ammend the above.
I can't "count" to 2^512, but I can't produce a numeric token in that range
(currently).  The strict sources include high precision arithmetic which will
only go up to 9,999,999,999--which is *way* less than 2^512.  However--it is
high enough (obviously).

>>> Native
>>> overloaded macros would also provide a workaround for the token
>>> pasting problem you've mentioned:
>
>> No the wouldn't.  The token pasting problem that I mentioned only
>> exists because there is no difference between ( placemarker ) and (
>> argument ).  Therefore, this would be ambiguous:
>>
>> #define MACRO()
>> #define MACRO(a)
>>
>> MACRO() // argument == placemarker?
>>         // or, no argument at all?
>
> Ahh... I hadn't thought of that (obviously :)  This should probably
> be a call to the nullary MACRO.  Users can explicitly request the
> unary MACRO with an empty argument easily enough:
>
> #define nothing
> MACRO(nothing)

I agree that in the scheme above, if there are no arguments, and a nullary macro
exists, choose the nullary macro.  The logic is pretty simple. ;)  However, the
above won't always work:

#define NIL

#define A() B()
#define A(x) B(x)

#define B() 1
#define B(x) 2

A(NIL) // ?

The problem here is that the argument is thoroughly expanded and rescanned prior
to insertion into the replacement list of A.  Rescanning therefore sees this:

B( )

...and would call the nullary B macro.

Granted, this is not a big problem.  I'm just pointing out why simulation of
MACRO( <placemarker> ) as opposed to MACRO() is not generally possible.  (Though
I don't think it really matters!) :)

>> Furthermore, the problems compound if you separate the "recursive"
>> style macros from the overloading idea.  Specifically, if an
>> identifier token that is found during the rescan of a macro's
>> replacement list that refers to a macro that is currently "disabled,"
>> the identifier token itself is permanently disabled--this is even
>> without an attempted invocation, such as:
>>
>> #define MACRO(x) x
>>
>> MACRO( MACRO )( 1 ) // MACRO( 1 )
>
> Right.  If you want this to expand to 1, you'd need to use a recursive
> macro.  Recursive macros would never be disabled.
>
>> No invocation is needed in order to disable specific identifiers.
>> So, either the entire overload set must be disabled, or the
>> overloading
>> can only work when macros are recursive.
>
> Probably the thing to do is disable only the nonrecursive overloads.

The problem is that there is no way to tell what overload is what when all you
have is the identifier itself.  The preprocessor disables the specific
identifier token itself when it encounters it if the corresponding macro is
disabled.  No invocation (or attempt at invocation) is necessary--which means
any specific overload could not be chosen.  Ultimately, what this means is 1)
the entire overload set must be disabled, or 2) a specific identifier token
would have to be only "tentatively" disabled--pending selection from an overload
set.  (The easy solution would be to only allow overloading of macros that are
recursive.)

> The point was that, with recursive macros and overloading, you could
> define a fully general list splitter (and other useful list
> manipulation macros, too :).

Yes, I know, and I would definitely like such a mechanism.  However, much of
this I can do already given a conformant preprocessor.  List manipulation
algorithms in my strict sources only require about 3/4 macros each.  However,
the mechanism has to jump through some hoops and use some advanced trickery to
achieve this.

Regards,
Paul Mensonides


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]


