Macros 对宏进行操作的预处理器宏?

Macros 对宏进行操作的预处理器宏?,macros,c-preprocessor,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 PR

以下是我的宏示例:

#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
您可以看到,当我不运行单元测试时,我希望我的
打印
\U
函数的计算结果为零,这样我就可以发送垃圾邮件,而不必担心它们在调试或生产过程中到处出现

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

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

INT
LONG
UINT
ULONG
HEX
FLT
PTR
STR
然后将它们全部插入到图案中

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

其中,
%LI%
表示列表中的一个项目。

您不需要更改所有
打印类型
宏的定义:因为它们都委托给
打印FMT
,您只需要更改该宏的定义

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

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

尽管不是很令人满意,但至少以下代码重用了 格式说明符部分。 我不确定这是否真的能帮助你,但以防万一,这可能是一个提示:

#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 );

希望这有帮助

像这样的东西怎么样:

#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() );

}
#包括
#定义标志
#ifdef标志
#定义SW(x,…)x###u1(uu VA_ARGS_uu)
#否则
#定义SW(x,…)x###u0(uu VA_uargs_uu)
#恩迪夫
#定义测试1(a)软件(测试1,a)
#定义测试1_0(a)10
#定义测试1_1(a)11
#定义测试2(a,b)软件(测试2,a,b)
#定义TEST2_0(a,b)20
#定义TEST2_1(a,b)21
#定义TEST3()32
内部主(空){
printf(“1.TEST1=%i\n”,TEST1(1));
printf(“2.TEST2=%i\n”,TEST2(1,2));
printf(“3.TEST3=%i\n”,TEST3());
}
可以通过参数数量而不是可变宏来定义SW1、SW2等

我希望它足够清晰,可以定义SW()来全面禁用所有 宏,具体取决于标志值。但是宏“定义”(通过软件)和“实现” 仍然需要不同的名称(没有“宏重载”),而且不可能 定义到宏中


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

我认为编译器会警告
语句对
0。你确实提出了一个关于我的打印依赖性的很好的观点,我可以利用它。然而,我仍然需要所有附加的
\U
宏,这样我就可以拥有每个宏的两个版本。我仍然想在我的非单元测试调试版本中使用它们。@Steven:我只需定义PRINT\u FMT(未使用的,未使用的)
,这样它就不会被导出。