在宏上运行的预处理器宏?

时间:2011-03-19 03:20:19

标签: macros c-preprocessor

以下是我的宏示例:

#define STR(val) #val
#define STRX(val) STR(val)
#define LINE_ STRX(__LINE__)
#define SRC_STR __FILE__":"LINE_
#define SRC_STRN SRC_STR"\n"

#define PRINT_IF(cond) ((cond)&&(printf("\""#cond"\" is true: "SRC_STRN)>=0))
#define PRINT_IFNOT(cond) ((!(cond))&&(printf("\""#cond"\" is false: "SRC_STRN)>=0))
#define PRINT_IFN PRINT_IFNOT
#define PRINT_IFEQ(a,b) PRINT_IF(a==b)

#define PRINT_FMT(val,fmt) printf(#val" = "#fmt": "SRC_STRN,val)
#define PRINT_INT(i) PRINT_FMT(i,%d)
#define PRINT_LONG(i) PRINT_FMT(i,%ld)
#define PRINT_UINT(i) PRINT_FMT(i,%u)
#define PRINT_ULONG(i) PRINT_FMT(i,%lu)
#define PRINT_HEX(i) PRINT_FMT(i,%x)
#define PRINT_FLT(flt) PRINT_FMT(flt,%g)
#define PRINT_PTR(ptr) PRINT_FMT(ptr,%p)
#define PRINT_STR(str) PRINT_FMT(str,%s)

我想定义另一个与此相关的宏列表,但我想避免键入所有内容。我已经写了一个例子:

#ifndef UNITTEST
#define PRINT_INT_U(x) ((void)sizeof(x))
#else
#define PRINT_INT_U(x) PRINT_INT(x)
#endif

我可以看到,当我没有运行单元测试时,我希望我的PRINT_ ... _U函数评估为空,这样我就可以对其进行垃圾邮件而不用担心它们会弹出所有调试或生产过程中的地方。

所以我的问题是,是否有一些使用预处理器生成新的#define语句的疯狂方法?我的猜测是没有......

编辑:我至少可以这样做吗?列出一个清单:

INT
LONG
UINT
ULONG
HEX
FLT
PTR
STR

然后将它们全部插入到模式中

#define PRINT_%LI%_U(x) PRINT_%LI%(x)

其中%LI%表示列表中的项目。

3 个答案:

答案 0 :(得分:1)

您无需更改所有PRINT_TYPE宏的定义:因为它们都委托给PRINT_FMT,您只需要更改该宏的定义。

#ifndef UNITTEST
    #define PRINT_FMT(unused, unused) 0
#else
    #define PRINT_FMT(val,fmt) printf(#val" = "#fmt": "SRC_STRN,val)
#endif

printf返回int,因此为了保持一致性,让无操作版本的类型为int是有意义的。)

答案 1 :(得分:0)

虽然不是很令人满意,但至少,以下代码重用了 格式说明符部分。 我不确定这对你有什么帮助,但以防这可能是一个暗示:

#define INT %d
#define LONG %ld
...and so forth...

#define PRINT(val,fmt) printf(#val" = "STRX(fmt)": "SRC_STRN,val)

#ifndef UNITTEST
#define PRINT_U(x,fmt) ((void)sizeof(x))
#else
#define PRINT_U(x,fmt) PRINT(x,fmt)
#endif

  int i;
  long l;
  PRINT( i, INT );
  PRINT( l, LONG );
  PRINT_U( i, INT );

希望这有帮助

答案 2 :(得分:0)

这样的事情怎么样:

#include <stdio.h>

#define FLAG

#ifdef FLAG
#define SW(x,...) x##_1(__VA_ARGS__)
#else
#define SW(x,...) x##_0(__VA_ARGS__)
#endif

#define TEST1(a) SW(TEST1,a)
#define TEST1_0(a) 10
#define TEST1_1(a) 11

#define TEST2(a,b) SW(TEST2,a,b)
#define TEST2_0(a,b) 20
#define TEST2_1(a,b) 21

#define TEST3() 32

int main( void ) {

  printf( "1. TEST1 = %i\n", TEST1(1) );
  printf( "2. TEST2 = %i\n", TEST2(1,2) );
  printf( "3. TEST3 = %i\n", TEST3() );

}

可以通过参数数量而不是可变参数宏来定义SW1,SW2等。

我希望它足够明确,可以定义SW()来普遍禁用所有 宏,取决于标志值。但宏“定义”(通过SW)和“实现” 仍然需要不同的名称(没有“宏超载”),它是不可能的 #define成宏。

但是,为每个宏写一个单独的#ifdef当然没有必要。