'How to redefine print function at runtime in C
I'm currently using a simple preprocessor switch to disable/enable my debug statements. I have printf retargeted to the UART output, and then define my print function in a globally included header (globals.h) to make it easy to disable all debugging like this:
#ifdef USE_UART
#define MY_PRINT(...) printf(__VA_ARGS__)
#else
#define MY_PRINT(...)
#endif
All my application files can then print debug messages over UART like this:
MY_PRINT("\t<<Battery Voltage: %d>>\r\n", vBat);
What I'm trying to do is have this be switched by external input (ie a button press) during run time. For example something like this:
void my_print(const char * pString){
if (uart_mode == UART_ON){
printf(pString);
}
}
Where uart_mode could be toggled via the external input. I'm having trouble figuring out how to pass variable arguements properly into printf through this function. Is this possible? Is there a better way to do it?
Solution 1:[1]
A decent approach that avoids conditionals at runtime (though it's still dynamic dispatch) and mimics function calls precisely (because it is a function call) would be:
typedef int (*printf_func_t)(const char *, ...);
int dummy_printf(const char *format, ...) {
return 0;
}
/* Set initial value based on initial uart_mode */
printf_func_t dynamic_printf = uart_mode == UART_ON ? &printf : &dummy_printf;
In some other toggle code (where uart_mode is changed), you'd just test and reassign:
dynamic_printf = uart_mode == UART_ON ? &printf : &dummy_printf;
Actual users then always call dynamic_printf in place of printf, and it calls whichever function is currently assigned to the function pointer. No read or test of uart_mode occurs when printing, it just calls whatever function is found at the time.
Solution 2:[2]
How about something like this:
#define MY_PRINT(...) \
do { \
if (uart_mode == UART_ON) \
printf(__VA_ARGS__); \
} while(0)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ShadowRanger |
| Solution 2 |
