Tyson Dowd <[EMAIL PROTECTED]> writes:
> Yep. It's just the "paste" operator for the pre-processor.
> C isn't a string based language so you can't do this at run-time, but
> you can play little tricks with ## at compile time using the
> preprocessor.
Tyson covered much of what I would have said, but I thought I'd
mention a few things.
There are things that everyone who gets introduced to the preprocessor
should note. First off, don't ever assume that the preprocessor has
any real sophistication. It doesn't implement a truly powerful macro
system like (for example) RXRS scheme. It really is just a *very*
dumb textual "search and replace". For example, this often looks OK
at first glance:
#define square(x) (x * x)
But it is broken in a number of ways. First off, if you were to say
square(x + y) this would get expanded into:
x + y * x + y
which, given the precedence of * over + is probably not what you
meant. To fix it, you need to define square like this:
#define square(x) ((x) * (x))
(I tend do overuse parens in C macro definitions. Better safe than
sorry...)
And even this might not be correct. Presume that you had a function
get_next_value that returned successive values an increasing series of
integers i.e. (1,2,3,4...). Now presume that the next value should be
5, and you call square(get_next_value()). You might expect to get 25
as the answer, but you'd actually get 30. That's because the
expansion looks like this:
(get_next_value()) * (get_next_value())
To fix this, you need to use a temporary variable, but standard C
AFAIK provides no way to do this cleanly. What you'd like to say is
something like this (which won't actually work):
#define square(x) { double tmp = x; x * x; }
The reason this won't work (in ANSI C) is that as I recall a {} scope
doesn't have a value, wo when expanded you'll get a syntax error:
foo = square(get_next_value());
turns into
foo = { double x = get_next_value(); x * x; }
What's worse, even if this did work, you'd have potential variable
shadowing problems. What if someone said:
foo = square(x);
Now the x in their call conflicts with the "x" used as a temporary in
the macro expansion. To solve all these problems, you need hygenic
type-safe macros as provided by scheme (and probably a few other
languages). In common lisp you can get by using (gensym) to create
guaranteed unique variable names, but that's a hack.
> Of course you could use a garbage collecting library (replaces malloc
> with a version that does garbage collection) but I think adding another
> dependency for gnucash would be a bit much right now.
And IMO better to do the work where you really need garbage collection
on the scheme side where it's handled "right".
> No problem, you're doing heaps of work on the code so I thought this
> would be a completely selfish way to get you to do more ;-)
ditto.
--
Rob Browning <[EMAIL PROTECTED]> PGP=E80E0D04F521A094 532B97F5D64E3930
--
Gnucash Developer's List
To unsubscribe send empty email to: [EMAIL PROTECTED]