如果我们想知道一个宏的值应该怎么办?
要么在代码里加一句printf
要么在编译的时候gcc -E
第一种方法需要程序运行起来,颇为麻烦
第二种方法无法应付下面这些情况
比如宏的值等于sizeof(struct xxoo)
比如宏本身就是一个复杂的运算(((2U) << (((0+8)+8)+13)) | (((‘W’)) << (0+8)) | (((7)) << 0) | (((((sizeof(int) == sizeof(int[1]) && sizeof(int) < (1 << 13)) ? sizeof(int) : __invalid_size_argument_for_IOC))) << ((0+8)+8)))
我设计了一个编译期打印宏值的方法,原理是利用gcc函数属性扩展warning和编译期运算
代码show_marco.h
#ifndef _SHOW_MACRO_H_
#define _SHOW_MACRO_H_
/*
SHOW_MSG(expression, true string, false string)
SHOW_MACRO(MACRO_NAME)
SHOW_MACRO(ENUM_NAME)
MACRO2STRING(MACRO_NAME)
zhaoxiaogang 2014-11-18
*/
#define MACRO2STRING_(M) #M
#define MACRO2STRING(M) MACRO2STRING_(M)
#define a_t_t_r(S) __attribute__((warning(S)))
#define SHOW_MSG__(E, S1, S2, N) \
int str1__##N(void) a_t_t_r(S1); \
int str2__##N(void) a_t_t_r(S2); \
int str0__##N(void) { return (E) ? str1__##N() : str2__##N(); } \
struct stru__##N { unsigned int check_expression : 1 + !(E); };
#define SHOW_MSG_(E, S1, S2, N) SHOW_MSG__(E, S1, S2, N)
#ifdef __COUNTER__
# define SHOW_MSG(E, S1, S2) SHOW_MSG_(E, S1, S2, __COUNTER__)
#else
# define SHOW_MSG(E, S1, S2) SHOW_MSG_(E, S1, S2, __LINE__)
#endif
#define j_(v) int show__0x##v(void) a_t_t_r(#v);
j_(0) j_(1) j_(2) j_(3) j_(4) j_(5) j_(6) j_(7) j_(8) j_(9) j_(a) j_(b) j_(c) j_(d) j_(e) j_(f)
#define k_(M,i,j) (((((M)+0ULL)>>((15-0x##i)*4))&0xF)==0x##j ? show__0x##j() : 0) +
#define SHOW_MACRO(M) \
int M##__eq(void) a_t_t_r(#M" = "MACRO2STRING(M)); \
int M##__lt(void) a_t_t_r(#M