考虑此程序:
#define MACRO \
srand(time(NULL)); \
if (rand() % 2) \
printf("A"); \
else \
printf("B");
int main() {
MACRO;
}
它等效于以下宏扩展程序:
int main() {
srand(time(NULL));
if (rand() % 2)
printf("A");
else
printf("B");
}
很显然,if
语句是在运行时而不是在宏扩展阶段执行的。如果if
语句是在编译时执行的,并且有语法引用(如Lisp),则我们可以(几乎)相等的概率获得程序A和A'。其中A:
int main() {
printf("A");
}
和A':
int main() {
printf("B");
}
就编译时评估的条件而言,有没有办法让GCC发出A或A'?
答案 0 :(得分:3)
有没有办法在C预处理器中执行任意代码?
否,这是原始(1989)C标准作者的故意设计决定。他们熟悉功能更强大的宏系统(例如,来自Lisp的宏系统,它确实允许在编译时进行任意计算),并且认为这些使理解一个陌生程序意味着什么变得太难了。
我不清楚您为什么要在编译时进行随机选择。如果您解释了更大的目标,我们可能会有所帮助。
答案 1 :(得分:1)
您无法在预处理器中执行代码。但是,您可以创建用于生成代码的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
printf("#include <stdio.h>\n");
printf("\n");
printf("int main()\n");
printf("{\n");
srand(time(NULL));
if (rand() % 2)
printf(" printf(\"A\");\n");
else
printf(" printf(\"B\");\n");
printf("}\n");
}
输出:
#include <stdio.h>
int main()
{
printf("A");
}
或者:
#include <stdio.h>
int main()
{
printf("B");
}
答案 2 :(得分:0)
要基于模数乘以随机数二的结果进行编译,我们需要使用BoostPP。
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/arithmetic/mod.hpp>
BOOST_PP_IF(BOOST_PP_MOD(RAND, 2), printf("A"); printf("B");)
您将需要使用-D
选项进行编译以从RAND
分配给/dev/random
,就像在注释中建议的那样。
以下是条件宏的一些实现细节,以带您了解其工作原理。模运算需要实现数据类型及其上的运算,在这里无法证明。
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
#define PROBE(x) x, 1,
#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x))
#define NOT_0 PROBE(~)
#define BOOL(x) COMPL(NOT(x))
#define IIF(c) PRIMITIVE_CAT(IIF_, c)
#define IIF_0(t, ...) __VA_ARGS__
#define IIF_1(t, ...) t
#define IF(c) IIF(BOOL(c))
#define EAT(...)
#define EXPAND(...) __VA_ARGS__
#define WHEN(c) IF(c)(EXPAND, EAT)
以及用法。请注意,WHEN(0)
不会展开,其他任何WHEN(arg)
都会展开。
WHEN(0) ( \
printf("A"); \
)
WHEN(1) ( \
printf("B"); \
)
WHEN(whatever) ( \
printf("this will expand too"); \
)
查看a concise intro to high level CPP和source for the macros in this example,以获取有关上面的宏的更多详细信息。