基于函数参数的C预处理器流控制
我想做的是这样的事情基于函数参数的C预处理器流控制,c,arguments,c-preprocessor,control-flow,C,Arguments,C Preprocessor,Control Flow,我想做的是这样的事情 #define TRIPLE_LOOP(code)\ //if there is something in code \ for(...) for(...) for(...) { code }\ //if code is empty then\ SOME_OTHER_CODE 所以 TRIPLE_LOOP(printf("muhahaha")) 将在输出上的三重循环内生成printf 及 将生成一些其他代码 这可能吗?您可以这样做: #define TRIPLE_LOO
#define TRIPLE_LOOP(code)\
//if there is something in code \
for(...) for(...) for(...) { code }\
//if code is empty then\
SOME_OTHER_CODE
所以
TRIPLE_LOOP(printf("muhahaha"))
将在输出上的三重循环内生成printf
及
将生成一些其他代码
这可能吗?您可以这样做:
#define TRIPLE_LOOP(code)\
for(...) for(...) for(...) { code }\
#define TRIPLE_LOOP()\
SOME_OTHER_CODE
我认为它会起作用:)不,你不能这样做。“code”的值在运行时定义,而宏在编译时被替换。您必须使用不同的宏定义。实际上您不能这样做,因为宏只能定义一次。您可以使用一些技巧来实现这一点:
#define TRIPLE_LOOP(CONDITION, ...)\
if(CONDITION) {\
for(...) for(...) for(...) { __VA_ARGS__; }\
} \
else {\
SOME_OTHER_CODE \
}
用法:
TRIPLE_LOOP(true, printf("muhahaha")); // `true` can be 1
TRIPLE_LOOP(false); // `false` can be 0
但请确保在传递参数时始终传递一个适当的bool
变量true
/false
。这几乎适用于我:)
#包括
#定义NARGS2(_1,N,…)N
#定义NARG(…)NARGS2(_VA_ARGS,1,0)
#定义三元组(…)\
做{\
如果(NARGS(_VA_ARGS){\
int i,j,k\
对于(i=0;i如果您的编译器是gcc或MSVC,那么下面的代码可能满足此目的
#define EXPAND( x ) x /* for MSVC */
#define CONCAT_( x, y ) x ## y
#define CONCAT( x, y ) CONCAT_( x, y )
#define CAR_( x, ... ) x
#define CAR(...) EXPAND( CAR_( __VA_ARGS__ ) )
#define VA_ARGS_(...) , ##__VA_ARGS__
#define VA_ARGS(...) VA_ARGS_( __VA_ARGS__ )
#define IS_EMPTY(...) CAR( VA_ARGS( __VA_ARGS__ ) 1 )
#define TRIPLE_LOOP(...) \
CONCAT( TRIPLE_LOOP_, IS_EMPTY(__VA_ARGS__) )(__VA_ARGS__)
#define TRIPLE_LOOP_1(...) SOME_OTHER_CODE
#define TRIPLE_LOOP_(...) for(...) for(...) for(...) { __VA_ARGS__; }
TRIPLE\u LOOP\u 1
对应于空参数大小写,并且TRIPLE\u LOOP\u
与其他情况相对应。
这里有一个测试。为什么不呢?TRIPLE_CODE()不是TRIPLE_CODE()。你也可以定义一个(p1,p2,p3),#定义一个(p1,p2),#定义一个(p1)etcnope:(它给出了测试。c:5:1:警告:“乐趣”重新定义的测试。c:3:1:警告:这是上一个定义测试的位置。c:8:17:错误:宏“乐趣”已传递1个参数,但接受just@Hasturkun:这确实很可怕;else
从未被执行过。然而,我正试图想出一个更可怕的解决方案,在else
也可以工作的地方:)我使用了GNU CPP扩展,使用了
令牌粘贴操作符。\define NARGS2(_1,_2,N,…)N
,和#定义NARG(…)NARGS2(,######!!!!!!!!!!!!!!!!!。
#include <stdio.h>
#define NARGS2(_1, N, ...) N
#define NARGS(...) NARGS2(__VA_ARGS__, 1, 0)
#define TRIPLELOOP(...) \
do { \
if (NARGS(__VA_ARGS__)) { \
int i, j, k; \
for (i=0; i<2; i++) { \
for (j=0; j<2; j++) { \
for (k=0; k<2; k++) { \
__VA_ARGS__; \
} \
} \
} \
} else { \
printf("NO ARGS"); \
} \
} while (0)
int main(void) {
TRIPLELOOP(printf("haha"); puts("!"));
TRIPLELOOP();
}
#define EXPAND( x ) x /* for MSVC */
#define CONCAT_( x, y ) x ## y
#define CONCAT( x, y ) CONCAT_( x, y )
#define CAR_( x, ... ) x
#define CAR(...) EXPAND( CAR_( __VA_ARGS__ ) )
#define VA_ARGS_(...) , ##__VA_ARGS__
#define VA_ARGS(...) VA_ARGS_( __VA_ARGS__ )
#define IS_EMPTY(...) CAR( VA_ARGS( __VA_ARGS__ ) 1 )
#define TRIPLE_LOOP(...) \
CONCAT( TRIPLE_LOOP_, IS_EMPTY(__VA_ARGS__) )(__VA_ARGS__)
#define TRIPLE_LOOP_1(...) SOME_OTHER_CODE
#define TRIPLE_LOOP_(...) for(...) for(...) for(...) { __VA_ARGS__; }