Macro/Literal Expressions

Questions about the BASICtools and MakeItC
Post Reply
joshklod
Posts: 7
Joined: Tue Feb 27, 2018 7:52 pm

Macro/Literal Expressions

Post by joshklod »

I often use macro expressions like the following in my code:

Code: Select all

#define LENGTH 16
if idx > LENGTH*3/4 then print "Almost full"
I can see that the preprocessor correctly expands this to:

Code: Select all

if idx > 16*3/4 then print "Almost full"
Is the Basic compiler smart enough to optimize`16*3/4` to `12`, or will the expression be evaluated at runtime?

Also, how does the compiler handle the following examples, where variables and literal expressions are mixed?

Code: Select all

dim a as integer
a = 3
' I would expect these expressions to be evaluated in the following ways:
print a*(5/2) ' => a*(2)  [6]  (A)
print a*5/2   ' => a*5/2  [7]  (B)
print 5*2*a   ' => (10)*a [30] (C)
print a*5*2   ' =? a*(10) [30] (D)
print a*6/2   ' =? a*(3)  [9]  (E)
Optimization of expressions A and C seems natural due to order of operations/evaluation order. Similarly, expression B cannot be optimized, because though algebraically equal, integer division would yield a different result.
Expressions D and E are less obvious. Though optimization would change the order in which the expression is evaluated, the result should be the same, unless integer overflow occurs. This would also be more difficult for the compiler to detect, as these situations often cannot be identified by syntax alone.

Edit:
What if I use `CONST` instead of `#define` in the first example? As in:

Code: Select all

CONST LENGTH = 16
if idx > LENGTH*3/4 then print "Almost full"



basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: Macro/Literal Expressions

Post by basicchip »

It is a little difficult for the user to figure out what the compiler optimizes for and what it does not.

I many cases if the compiler thinks the expression is a constant it evaluates it immediately. I do have a tool I can use which dumps out compiled code in the opcode format we use. DEBUG mode if you will.

In the first case

Code: Select all

CONST LENGTH=16
if idx > LENGTH*3/4 then print "Almost full"
It currently does not optimize. But if you had written

Code: Select all

CONST LENGTH=16
if idx > (LENGTH*3/4) then print "Almost full"
As in this case it evaluates the expression inside the () and sees it is a constant. Fooled myself on this one, in that it does pre-evaluate if you use a #define rather than a CONST. So there is room for compiler improvement. I usually use #define (force of habit, and also more typical of C programming)

As for you other examples A and C are optimized, B is not. And D and E are not, really D might expected to be, but E would be a bit trickier for the compiler.

One way you could tell is by timing the operations, which I often do, enclosing them in

Code: Select all

i=1000000
while x
  .. whatever code...
  i =i-1
loop

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: Macro/Literal Expressions

Post by basicchip »

PS these optimizations are only done on integers currently.

joshklod
Posts: 7
Joined: Tue Feb 27, 2018 7:52 pm

Re: Macro/Literal Expressions

Post by joshklod »

Thank you for the info!

To be clear (maybe my edit was confusing), my first example uses `#define`. Are parentheses required to trigger optimization in this case?

It sounds like I can guarantee optimization as long as I wrap constant expressions (or sub-expressions) in parentheses. This is probably a good habit to get into anyway.

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: Macro/Literal Expressions

Post by basicchip »

No it was me, I tried CONST first and that is a function of the compiler.

#define is done by the preprocessor, separate from the compiler, so those replacements are done to the source before the compiler sees them.

Post Reply