swestrup: (Default)
[personal profile] swestrup
Since I'm awake way too early, and drinking caffeine, I've been thinking strange things about extending CPP. Mainly because I have been reading the Boost Preprocessor libraries to see how they implemented things. In short, its obvious that they used a combination of utterly gormless stubborness, and a preprocessor-header generator. This is because they have 256 versions of almost every macro they defined, as well as any macros it may depend on. Sometimes they have 5 or 6 sets of 256 macros so they can nest. Eeep.

I've been wondering what the simplest extension to CPP would be that would greatly reduce the difficulty of writing the Boost PP libraries, while simultaneously not breaking existing code. I came up with one, but its kinda ugly.

Ideally, one would want to introduce a new CPP operator such as #eval(x) which simply returns the expansion of x as it would be evaluated on a #if line (with all booleans yielding 0 or 1). A macro inside a #eval() would be expanded, even if it appears in the expansion of that macro. Thus one could now explicitly request recursion. With this one could write something like:

#define ARG2_0(x,y) x
#define ARG2_1(x,y) y
#define IF_(b,x,y) ARG2_##b(x,y)

#define IF(b,x,y) IF_(#eval(b),x,y)
#define IFDEF(m,x,y) IF(defined(m),x,y)

#define FAC(n) IF( (n<=1), 1, #eval(FAC(n-1)))

(There's some handwaving above. I'm not sure that, as written, FAC would really work within CPP's rules without a few more levels of indirection, but I'm fairly sure it can be written to work). Now, actually using #eval() as the operator could cause all sorts of conflicts, and the only thing I've been able to think of (other than introducing another syntactic marker like @), is to hijack the new _Pragma operator for this. Thus, one would need to actually write:

#define PRAGMA(x) _Pragma(#x)
#define EVAL(x) PRAGMA(GCC oper eval x)

#define ARG2_0(x,y) x
#define ARG2_1(x,y) y
#define IF_(b,x,y) ARG2_##b(x,y)

#define IF(b,x,y) IF_(EVAL(b),x,y)
#define IFDEF(m,x,y) IF(defined(m),x,y)

#define FAC(n) IF( ((n)<=1), 1, EVAL(FAC(n-1)))

Which is either lots better or lots worse, depending on how you look at it. What thinks people?

It would be non-trivial to implement in, for instance, GCC because their implementation of _Pragma is already a horrible hack of their implementation of #Pragma which is a horrible hack of their implementation of command-line options (I just looked). Still, it looks to be less than a weeks work (part time). I wonder if suggesting an extension, with a patch, is a good idea, or a stupid one?

Date: 2006-06-28 01:27 pm (UTC)
From: [identity profile] sps.livejournal.com
I don't believe #eval would break anything. # is presently only permitted (I believe) when is a parameter. So you would need #define foo(eval) to hide #eval, but that's all.

The other things that's sorely needed is to recognise #define in a macro body, of course.

Oh, and I was wrong: it's not that #include foo(bar) is illegal, it's that there's precious little you can do with it. One would LIKE to be able to get bar bound to a symbol inside the include, but there's just no way without having populated directories of syntax interpreter stubs!

Date: 2006-06-28 05:34 pm (UTC)
From: [identity profile] sps.livejournal.com
Surely so, but this doesn't matter. Just be sure that the presence of a parameter named 'eval' disables your extension, and you are home free. For a change, you are saved by the fact that macros can't substitute into macro definition parameter lists - that string 'eval' must be physically present in any conflicting legacy code.

January 2017

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
293031    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 14th, 2026 10:57 pm
Powered by Dreamwidth Studios