#define DebugPointer(p) \
{ \
__typeof__(p) p1 = p; \
printf("%8s %20s: %p\n", #p, "address", (void*)&(p1)); \
printf("%8s %20s: %p\n", #p, "points to", (void*)(p1)); \
}
Итак, вы печатаете адрес p1
, который является локальным для каждого вызова DebugPointer
, поэтому он может быть одинаковым при каждом вызове.
похоже, цель p1
состоит в том, чтобы избежать многократных вычислений макропараметра p
.Чтобы достичь цели печати, вы можете изменить макрос, чтобы получить адрес заранее.
#define DebugPointer(p) \
do { \
__typeof__(&(p)) p1 = &(p); \
void *p2 = *p1; \
printf("%8s %20s: %p\n", #p, "address", (void*)p1); \
printf("%8s %20s: %p\n", #p, "points to", p2); \
} while(0)
Вот определение Sasprintf
, которое я нашел онлайн :
#define Sasprintf(write_to, ...) { \
char *tmp_string_for_extend = (write_to); \
asprintf(&(write_to), __VA_ARGS__); \
free(tmp_string_for_extend); \
}
Он использует временную функцию для хранения исходного указателя, который должен был быть выделен предыдущим вызовом для Sasprintf
(или инициализирован для NULL
).Вызов asprintf
может измениться, куда он указывает.Теперь макрос может вызывать free
для исходного указателя.
Чтобы избежать многократных вычислений параметра write_to
, его адрес можно получить заранее.
#define Sasprintf(write_to, ...) do { \
char **dest = &(write_to); \
free(*dest); \
asprintf(dest, __VA_ARGS__); \
} while(0)