[futurebasic] Re: C Style Macros?

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : December 1997 : Group Archive : Group : All Groups

From: Rick Brown <rbrown@...>
Date: Sun, 21 Dec 1997 13:17:12 -0600
Terence Jordan wrote:
> 
> --
> I was recently playing with some C source; and I came across some of these
> "Macro" Statements
> 
> >BYTE bfyr;
> >/* For convenience */
> >#define A bfyr
> 
> As I see it, these Macros mean that if I were to say A=5, bfyr would equal 5??

That's basically right.  The macro means, "Wherever "A" is used as an
identifier in this source file, put "bfyr" there instead."  One of the
side effects of that is that an assignment to "A" would result in bfyr
changing value, as you've noted.

> I'm sure there's a tricky way to do this successfully... is there?
> 
> I'm thinking:
> DIM A;0
> DIM bfyr;1
> 
> And then I can say:
> A=5
> print bfyr
> and it will print "5"

You've got the right idea, but it won't work in this particular case
because of the slightly clumsy way that FBII implements byte variables. 
In the code above, bfyr is declared as a byte variable, but "A" is
declared as the default type (usually a 16-bit integer).  This means
that only the _first_ byte of "A" will overlap in memory with bfyr's
single byte.  The memory allocations for the two variables look like
this:

      |-----------------|-----------------|
      |     bfyr /      |                 |
      | 1st byte of "A" | 2nd byte of "A" |
      |-----------------|-----------------|

If you say "A = 5", the left-hand byte gets "00000000" and the
right-hand byte gets "00000101".  But since bfyr is equivalent only to
the left-hand byte, when you say "PRINT bfyr", you'll get 0.

If you had defined bfyr as short integer (same type as "A"), like so:

DIM A;0
DIM bfyr

then things would be different.  In this case, "A" and bfyr are entirely
synonymous, and they're just two different names for the same (2-byte)
area of memory.  In this case, "A=5:PRINT bfyr" would indeed produce
"5".

> I seem to have solved the original question just by thinking it through, so
> here's three other questions...
> 
> #1, will that work all the time?

As long as the two variables are of the same type, as already
discussed.  Sometimes it's _useful_ to have them be of different types,
but not if you want to use one name as a synonym for the other.

> #2, is that what a Macro does to begin with?

No.  It has some of the same side effects, but it does it in an entirely
different way.  A macro essentially looks through the source code and
replaces all occurrence of a particular identifier with some replacement
string, _before_ compiling.  In particular, the identifier in a macro
(the "A" in "#define A...") is _not_ a variable and does not take up any
storage space.  For example, this macro:

#define pi 4*ATN(1)

...would turn this line:

piCubed = pi * pi * pi;

...into this:

piCubed = 4*ATN(1) * 4*ATN(1) * 4*ATN(1);

(that's an example of when _not_ to use a macro, because it makes your
program do the ATN calculation 3 times--very inefficient).

> #3, will a @A and @bfyr be equal to each other? They would share the same
> pointer, correct?

Yes, they will.  That's a result of the ";0" syntax, which means: "Begin
the next variable zero bytes past the beginning of this one."  As
discussed above, though, that does not necessarily mean that "A" and
bfyr will be evaluated in the same way.

> Thanks...

You're welcome.

- Rick