Society of Robots - Robot Forum

Software => Software => Topic started by: corrado33 on April 23, 2010, 10:22:53 AM

Title: Question about variable types in #Define statements
Post by: corrado33 on April 23, 2010, 10:22:53 AM
I was looking through the SoR_Utils today, and I saw these statements...

#Define PORT_ON ( port_letter, number)  .... other stuff

What I want to know is, how can you pass something like "DDRD" or "PORTD" into "port_letter"?  DDRD is technically a string, correct?  Why aren't there variable types in Define statements, like there are in functions.  If I wanted to pass something like DDRD to a function, would I have to use strings?

Thanks in advance...

EDIT:  Geeze I really should do more research before I post...  These are considered macros, and the exact text that you put into the PORT_ON(something, something) statement gets directly pasted into the code you have afterwords.  

So I guess my real question is Why use functions when you can use use macros?
Title: Re: Question about variable types in #Define statements
Post by: waltr on April 23, 2010, 11:01:01 AM
Glad you found part of the answer.

Quote
So I guess my real question is Why use functions when you can use use macros?

This depends on whether you wish to optimize code speed verse code size.
A function needs to be called and returned from. This produces code instruction cycle overhead (extra time) but the function is only in one place in the code.
A MACRO is a text substitution during pre-compile (pre-process) so a macro used multiple times is in the code in multiple places. It doesn't have the instruction cycle overhead of a function so executes faster but takes more code space.

Another use of Macros is to make later changes to constants easier and more readable code.
Say you have a UART and a value to set the baud rate. By using macros you can have several pre-defined baud rate values defined as the baud rate then in the UART set-up use the macro. Example:

#define Baud_9600 25
#define Baud_4800 50

So instead of:
baud_reg = 25;
you use:
baud_reg = Baud_9600;
if you later wish to change the baud rate to 4800 then you just use the macro which is human readable rather than some constant that you have to look up or re-calculate. This also makes read your code more understandable as "baud_reg = 50;" does mean much without digging out the data sheet whereas "baud_reg = Baud_4800;" is readily apparent.

The two marcos I used above does not make the code larger as the pre-processor only substitutes a macro that is used.

Does that help answer your question?
Title: Re: Question about variable types in #Define statements
Post by: corrado33 on April 23, 2010, 11:06:46 AM
Does that help answer your question?

That makes a lot of sense.  Functions are actual parts of the programming, while macros are basically substitutions.  They make your code "look" prettier, but when the code is compiled, all those substitutions are made, and your code is ugly again.  (Of course, you'd never know this, since it'd be in HEX form).  So macros make code quicker by making substitutions when the code compiles? 

Thanks so much, that clears a lot of stuff up. 
Title: Re: Question about variable types in #Define statements
Post by: chelmi on April 23, 2010, 11:23:21 AM
So I guess my real question is Why use functions when you can use use macros?

Many reasons! Here is a few:

- code size: macro are expanded at compile time, i.e. the macro is replace by it's value when you compile the file. So for one macro used 1000 times, you will have 1000 semi-identical code fragment in you object file. For a (not inlined) function, you will have just 1 piece of code for the function and 1000 function calls.
- some constructs are simply not possible with macros: recursive calls, function pointers.
- modularity: you cannot "precompile" a macro. Everything has the be recompiled, every time. (no incremental compilation)
- No type checking: As you've seen yourself, there is no type checking with macros. This code will show you why this is really bad:

Code: [Select]
typedef struct {
 int field;
} int_struct;

typedef struct {
 char* field;
} pointer_struct;

#define PRINT_STRUCT(s) printf("%s\n", s.field);

void print_struct(pointer_struct s)
{
  printf("%s\n", s.field);
}

int main(void)
{
  int_struct foo;
  foo.field = 3;
  PRINT_STRUCT(foo); //This will crash during execution
  //print_struct(foo); //This would not compile
}

Title: Re: Question about variable types in #Define statements
Post by: corrado33 on April 23, 2010, 12:10:01 PM
- code size: macro are expanded at compile time, i.e. the macro is replace by it's value when you compile the file. So for one macro used 1000 times, you will have 1000 semi-identical code fragment in you object file. For a (not inlined) function, you will have just 1 piece of code for the function and 1000 function calls.

Ahhh, that makes sense!  So really that's why macros are generally only used for one line things...  That makes a lot of sense.