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]

Reply via email to