是否可以做这样的事情:
#define F(x) \
#ifdef DOUBLE \
2*x \
#else \
x \
#endif
这样当我使用F
时,它扩展到什么取决于是否定义了宏DOUBLE
?我不这么认为,但我很有希望。 GNU扩展很好。
修改 为了回答一些答案,我实际上是用它来做一些代码生成,代码稍有不同,具体取决于它的定义位置。由于包含某些文件的顺序以及需要定义相关宏的位置,以此方式切换它需要一些因子。我可能不得不这样做,但如果我不必从这个角落重新点燃自己,我会很激动!
答案 0 :(得分:13)
有什么问题
#ifdef DOUBLE
#define F(x) (2 * (x))
#else
#define F(x) (x)
#endif
答案 1 :(得分:8)
如果我们可以限制问题,你可以做到这一点。具体来说,如果您可以保证DOUBLE
是
#define DOUBLE
),然后你可以使用带有标记连接的间接方法:
#define F_IMPL_(x) DOUBLE_IS_DEFINED
#define F_IMPL_DOUBLE(x) DOUBLE_NOT_DEFINED
#define F_1(x, m) F_2(x, m)
#define F_2(x, m) F_IMPL_ ## m ( x )
#define F(x) F_1(x, DOUBLE)
用法示例:
F(t)
#define DOUBLE
F(t)
预处理后的结果:
DOUBLE_NOT_DEFINED
DOUBLE_IS_DEFINED
如果DOUBLE
(如果已定义)被定义为扩展为单个已知令牌的宏,如果该令牌可以构成标识符的一部分(例如,TRUE
或1
)。要处理此问题,您只需将F_IMPL_
宏重命名为F_IMPL_{TOKEN}
(例如F_IMPL_TRUE
或F_IMPL_1
)。
答案 2 :(得分:4)
为什么不以相反的方式进行嵌套?
#ifdef DOUBLE
#define F(x) (2*(x))
#else
#define F(x) (x)
#endif
答案 3 :(得分:3)
没有。您可以做的最接近的事情是将其放在头文件中,并在每次您关心的定义发生变化时#include该头文件。这有时称为“X”模式,因为X
用作更改定义的宏。
例如,该模式的一个常见用法是自动生成枚举值的字符串名称:
// File myenum_values.h
// NOTE: _no_ header guards so we can include this file multiple times
X(Apple)
X(Orange)
X(banana)
// File myenum.h
enum Fruit
{
#define X(x) x,
#include "myenum_values.h"
}
const char *FruitNames[] =
{
#undef X
#define X(x) #x,
#include "myenum_values.h"
};
// We now have an array of fruit names without having to define the enum twice