Subject:
|
Re: NQC preprocessor behavior - constants evaluated?
|
Newsgroups:
|
lugnet.robotics.rcx.nqc
|
Date:
|
Tue, 17 Aug 2004 01:59:13 GMT
|
Viewed:
|
5461 times
|
| |
| |
In article <I2InLL.yJw@lugnet.com>, "Brian Davis" <brdavis@iusb.edu>
wrote:
> Pardon a basic, low-level question, but I'm trying to minimize memory &
> execution time. Does the NQC preprocessor precalculate constant expressions
> before the compile pass? For instance:
The preprocessor only evaluates expressions if they are used in a
conditional preprocessor statement (i.e. #if), otherwise they are simply
treated as a series of tokens for the compiler to deal with. However,
the compiler does evaluate expressions that it believes are constant.
>
> #define CONST 100
> #define HALF CONST/2
>
> task main()
> {
> int x,y;
> x = 3 * HALF;
> y = 10 / 2 * x;
> }
>
> When this compiles, will the bytecode have the variable x assigned a single
> constant, or will the bytecode actually be doing time (and memory) wasting
> things like dividing 100 by 2 (in the second #define), or multipling a
> constant
> by another constant (the assignment statement).
After the preprocessor, that first assignment looks like this (parens
added to emphasize order of operations):
x = (3 * 100) / 2;
The compiler will evalutate this to 150 and no math will be performed by
bytecodes.
Note - this is probably not the order of operations you want. It
doesn't make a difference here, but if CONST was odd, then the order
would be significant:
(3 * 7) / 2 = 10
3 * (7 / 2) = 9
Generally it is a good idea to use parentheses around computed values in
#defines:
#define HALF (CONST/2)
> And could it take the second
> assignment statement and simplify it to a single math operation (5 * x).
> Anybody?
The compiler will do that simplification as well. Note that order is
very important. Make sure the constants all combine before operating on
a variable:
y = 1 + x + 2 => y = (1 + x) + 2 ; two additions
y = 1 + 2 + x => y = (1 + 2) + x => y = 3 + x ; one addition
Good compilers take advantage of mathematical identities to re-arrange
that first case, but I never bothered to implement it for NQC.
If you're really curious, you can have NQC generate a code listing and
then examine the individual bytecodes. Most of the IDEs have some sort
of menu option for this. When using the command line, add -L before the
filename:
nqc -L foo.nqc
The listing for your example looks like this:
*** Var 47 = x
*** Var 46 = y
*** Task 0 = main
000 pwr ABC, 7 13 07 02 07
004 dir ABC, Fwd e1 87
006 setv var[47], 150 14 2f 02 96 00
011 setv var[46], 5 14 2e 02 05 00
016 mulv var[46], var[47] 54 2e 00 2f 00
The "pwr" and "dir" bytecodes are by default put at the beginning of a
program (use "#pragma noinit" to supress this). You can see the
assignment of x in the third bytecode, the fourth moves 5 into y, and
the fifth multiplies y by x.
Dave Baum
|
|
Message is in Reply To:
| | NQC preprocessor behavior - constants evaluated?
|
| Pardon a basic, low-level question, but I'm trying to minimize memory & execution time. Does the NQC preprocessor precalculate constant expressions before the compile pass? For instance: #define CONST 100 #define HALF CONST/2 task main() { int x,y; (...) (20 years ago, 16-Aug-04, to lugnet.robotics.rcx.nqc)
|
3 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|