Macro usage for changing values

4 replies [Last post]
dsotmman
Title: NooBot
Joined: 04/22/2013
Posts:
BotPoints: 6
User offline. Last seen 9 years 8 weeks ago.

I am trying to make my code more compact, and ultimately more readable using macros in place of lengthy function names...

I am wondering, however, if something like this is condoned:

#define ETSCAN analog10(0)

Assuming an ETscanner was to be plugged into analog10, would this value reflect accurately the current value? For example, in

while(ETSCAN < 200) {}

would the while loop ever break, as in, would the value of ETSCAN ever refresh past the first value it took?

Thanks.

KCotrone
Title: NooBot
Joined: 01/29/2013
Posts:
BotPoints: 38
User offline. Last seen 8 years 50 weeks ago.

It would. I wouldn't recommend using preprocessor macro like that. The way #define works is that, at compile time, it replaces every instance of ETSCAN with analog10(0) and then it compiles the code. I would recommend using:

  1. #define ETPORT 0

and then
  1. while(analog10(ETPORT) < 200)
  2. {
  3. msleep(10);
  4. }

Jeremy Rand
Jeremy Rand's picture
Title: Botball Youth Advisory Council
Joined: 04/03/2009
Posts:
BotPoints: 1168
User offline. Last seen 7 years 20 weeks ago.

In general, #define is used for conditional compilation (e.g. with #ifdef). Using it as a substitute for functions or variables isn't really recommended, because it makes certain kinds of analysis harder (e.g. the GDB debugger can't handle #defines properly unless you jump through some fairly weird hoops).

I would instead recommend this:

  1. int ETScan()
  2. {
  3. return analog10(0);
  4. }

If you're worried about execution speed, consider that in Botball, 99% of the time the limiting factor is something other than your code's execution speed. However, if you really want to make this code execute as fast as the #define, look up the "inline" keyword.

  1. inline int ETScan()
  2. {
  3. return analog10(0);
  4. }

The inline keyword will instruct the compiler to replace all calls to ETScan with a copy of the function's contents, which will use more space but run faster (same as #define), but your code will still be handleable by debuggers. That said, in Botball you don't need inline... the Link is plenty fast enough to handle your code without inline.

-Jeremy Rand
Senior Programmer, Team SNARC (2012-2013), Norman Advanced (2010-2011), Norman HS (2008-2009), Norman North (2005-2007), Whittier MS (2003-2004)
2012-2013 VP of Tech, 2011 President, Botball YAC (2009-2013)
Mentor, Alcott and Whittier MS

ruler501
ruler501's picture
Title: NooBot
Joined: 01/29/2012
Posts:
BotPoints: 367
User offline. Last seen 7 years 21 weeks ago.

In botball the teams I have been on taught that you should use defines to abstract away global constants(I know you could use global variables, but using globals can be a slow down and explaining them confuses less adept programmers)
Would that not be a good use of them. I see them used like that in plenty of real world programs that I can't see a problem with it.

Jeremy Rand
Jeremy Rand's picture
Title: Botball Youth Advisory Council
Joined: 04/03/2009
Posts:
BotPoints: 1168
User offline. Last seen 7 years 20 weeks ago.

@ruler501, The const keyword should be used for that, not #define. const has the advantage of not messing up debuggers. The reason Botballers use #define for constants is historical: Interactive C did not support the const keyword, and KIPR didn't make any effort to re-educate teams after they switched to GCC.

-Jeremy Rand
Senior Programmer, Team SNARC (2012-2013), Norman Advanced (2010-2011), Norman HS (2008-2009), Norman North (2005-2007), Whittier MS (2003-2004)
2012-2013 VP of Tech, 2011 President, Botball YAC (2009-2013)
Mentor, Alcott and Whittier MS