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