The question is how do I write, or what do I do to compile a program with one of two subroutines that are named the same?
Let me try to break it down. I have a project which will have two versions, but don't want to maintain two programs, when less than 25% of the programming different between them. One of the items that is different is the menu subroutine (called display_menu()). I tried to create display_menu1() and display_menu2() and use a #define and if statement to select the correct function call. Problem is I ran out of space. There is enough space for one menu or the other, but not for both. The fact is that I don't need both. It is either version A or version B. It will never be switched between them.
I would like is to remove the current #define and if statement combo, call only display_menu() and use another command or directive to switch between compiling the two menus. The program will have display_menu() twice, but only one gets compiled in. Is this possible?
Another option would be to move the menus to two separate files (which would make three in total, 1-main program, 2-menu A, 3-menu B) and use a directive to only compile main program & menu A or main program & menu B. Can it be done this way?
Is there another option? (besides a larger board, ie., upgrading from UNO to MEGA)
If you have a preprocessor conditional that's false, the code inside will definitely not be compiled.
The compiler will also try to optimize out any code that can be determined at compile time to never be used.
So it's not clear to me how you're ending up with the unused code causing you to run out of space. It would probably be helpful if you posted the code.
adwsystems:
The program will have display_menu() twice, but only one gets compiled in. Is this possible?
Sure, you can do something like this:
#ifdef MODE_A
display_menu() {
// Mode A code
}
#else
display_menu() {
// Mode B code
}
#endif
You can be sure that only one of those will be compiled. There are other ways to do this as well. My advice is to avoid the use of the preprocessor unless you have no other option. Usually I would only do something like this if one of the two required a library that the other didn't and I only wanted to include the library in the mode that required it. In that case, there is no option other than to use the preprocessor since any compile time options will fail due to references to the undeclared library code.
adwsystems:
Another option would be to move the menus to two separate files (which would make three in total, 1-main program, 2-menu A, 3-menu B) and use a directive to only compile main program & menu A or main program & menu B. Can it be done this way?
Yes, if the code is in a .h file. You can do this:
//#define MENU_A
#if defined MENU_A
void display_menu() {
// version A of the function
# pragma message "Version A of display_menu()"
//...
}
#else
void display_menu() {
// version B of the function
//...
# pragma message "Version B of display_menu()"
}
#endif
void setup() {
}
void loop() {
display_menu();
}
display_menu() {
// Mode A code
} #else
display_menu() {
// Mode B code
} #endif
You can be sure that only one of those will be compiled. There are other ways to do this as well. My advice is to avoid the use of the preprocessor unless you have no other option. Usually I would only do something like this if one of the two required a library that the other didn't and I only wanted to include the library in the mode that required it. In that case, there is no option other than to use the preprocessor since any compile time options will fail due to references to the undeclared library code.
The compiler is going to see that there is absolutely no way the mode B code will be needed, so it will just optimize it out. This version of the code is much easier to read and debug than the nasty code that tends to result from using the preprocessor. There are times when the compiler won't be able to optimize things out so it really depends on the specific situation but it does generally do a very good job. Now if the value of modeA was dependent on runtime conditions (a pin state, for example), the compiler would have no way of knowing whether it can optimize that code out, so it won't.
You can help the compiler to optimize out unused functions in your sketch by making them static. This limits their scope to that translation unit. I also like that it enables helpful "defined but not used" warnings.
For example, the BareMinimum sketch:
void setup() {}
void loop() {}
compiles to:
Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
Sketch uses 1332 bytes (4%) of program storage space. Maximum is 32256 bytes.
Global variables use 184 bytes (8%) of dynamic memory, leaving 1864 bytes for local variables. Maximum is 2048 bytes.
Make the unused function static and the problem is solved:
Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.