To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.nqcOpen lugnet.robotics.rcx.nqc in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / NQC / 1690
1689  |  1691
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
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR