Implementing functions through macros is a nightmare with bool. I've defined macros for the head and body of a (generic) function. When using bool type, results are weird.
I get that this is the kind of stuff you generally want to avoid for maintainability ~ but in my case it's a collection of really similar callback functions and a really harsh abbreviation.
So the goals are actually maintainability and readability, especially code coherence.
#include <stdio.h>
#include <stdbool.h>
#define FUN_H(TYPE) \
void fun_##TYPE( void )
#define FUN(TYPE) \
FUN_H(TYPE) { \
printf("Type is " #TYPE ".\n"); \
}
FUN_H(int);
FUN_H(bool);
FUN(int);
FUN(bool);
int main(void) {
fun_int();
fun_bool();
}
Reading the code, I would expect the output "Type is int." and "Type is bool."
Actually, to make the code compile (current gcc/clang) last call must be changed to fun__Bool(); and the header to FUN_H(_Bool); -- which actually makes sense if you know your C99, but produces incoherent code.
_Bool type directlyFUN_H(_Bool);
FUN(_Bool); // or FUN(bool);
int main(void) {
fun__Bool();
}
FUN() macro#define FUN(TYPE) \
void fun_##TYPE( void ) { \
printf("Type is " #TYPE ".\n"); \
}
typedef for _Bool
typedef _Bool mybool;
FUN_H(mybool);
FUN(mybool);
int main(void) {
fun_mybool();
}
bool into a typedef
#undef bool
typedef _Bool bool;
FUN_H(bool);
FUN(bool);
int main(void) {
fun_bool();
}
So what should I do?
It's the inner FUN_H macro call that expands bool to _Bool if bool is a macro. If you lose the inner FUN_H macro and write FUN directly like so:
#include <stdio.h>
#include <stdbool.h>
#define FUN_H(TYPE) \
void fun_##TYPE( void )
#define FUN(TYPE) \
void fun_##TYPE( void ) { \
printf("Type is " #TYPE ".\n"); \
}
FUN_H(int);
FUN_H(bool);
FUN(int);
FUN(bool);
int main(void) {
fun_int();
fun_bool();
}
then you'll get fun_bool as expected, even if bool is a macro.
As mentioned, passing TYPE to any intermediate macro will force its expansion before further processing. So the concatenation must happen as early as possible, before passing TYPE anywhere. To achieve it without repeating ourselves too much, we can just delegate to a third macro
#define FUN_H(TYPE) \
FUN_H_(fun_##TYPE)
#define FUN_H_(NAME) \
void NAME( void )
#define FUN(TYPE) \
FUN_H_(fun_##TYPE) { \
printf("Type is " #TYPE ".\n"); \
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With