I would like to do conditional compiling and include different C files based on the hardware being used. For example:
#ifdef HARDWARE_MODULE_1
#include "hardware_module_1.c"
#endif
#ifdef HARDWARE_MODULE_2
#include "hardware_module_2.c"
...
Everything works fine this way only debugging becomes a problem. Breakpoints don't work correctly when placed in the C file that's included that way. The program ends up breaking somewhere else random in the code (different C file altogether) When I manually add file to the project everything seems to be working fine. I'm using uVision V4.60.6.10
One more thing. C language (and compiler) doesn't have a concept of source files and header files. It is just merely a convention. So preprocessor just copies and pastes them before compilation begins.
"So preprocessor just copies and pastes them before compilation begins."
But that is a huge simplification that isn't really fully applicable when you start to thin about debugging.
What if I do this?
#define PREFIX "com1_" #define RXSIZE 32 #define TXSIZE 32 #include "uart.c" #undef PREFIX #undef RXSIZE #undef TXSIZE #define PREFIX "com2_" #define RXSIZE 128 #define TXSIZE 1024 #include "uart.c" ... com1_init(9600); com2_init(115200);
and then in "uart.c" have
uint8_t _(rxbuf)[RXSIZE]; uint8_t _(txbuf)[TXSIZE]; void _(init)(void) { ... }
The above can be correct C code. And the compiler can manage to produce a valid program. But every line in "uart.c" is used to produce two separate serial port implementations. So creative use of the preprocessor resulted in "template" support in C.
But a breakpoint at uart.c:152 would be the same source line that is used in both com1_init() and com2_init(). How would the IDE and the debugger then know how to translate from a source line into an offset into the binary when you try to set a breakpoint? Or should the IDE+debugger recognize the above and set a breakpoint both in com1_init() and in com2_init()? But if you then wait until the debugger breaks on com1_init() and you then press a key to remove a breakpoint - should both breakpoints be removed? Or just the com1_init() breakpoint?
C++ compiler vendors have to invest a huge amount of time to try to see how far they can get their debuggers to handle included code, because of class method code, template code, inlined code, ...
So "valid code" does not mean you have the right to demand that the debugger - any debugger - will be able to reverse-engineer what to actually do in all situations.
In the end, each and every developer will still have to stand for the consequences if they make an incorrect assumption.