C / C ++ #define宏内宏?

时间:2012-02-24 13:22:49

标签: c++ c c-preprocessor

我想要像:

#define C_OR_CPP(C__, CPP__) #ifdef __cplusplus\
CPP__\
#else\
C__\
#endif

有可能吗? 也许是#include的一些肮脏的黑客?

原因: 我创建一个标题,其中结构使用类型vector<stuff>*的成员变量,但在C中我希望​​它只是void*,你知道。

TIA

4 个答案:

答案 0 :(得分:11)

有什么问题
#ifdef __cplusplus
#define C_OR_CPP(C, CPP) CPP
#else
#define C_OR_CPP(C, CPP) C
#endif

(将双下划线的名称留给每个菲涅耳评论的实现)

答案 1 :(得分:1)

不在C ++中。但你可以

#ifdef __cplusplus
# define CPP
#else
# define C
#endif

我认为这只是你的一个病态例子。另请注意,双重下划线保留给库实现者(参见17.6.4.3.2全局名称)。

  

vector ,但在C中我希望​​它只是无效,你知道。

那么,什么反对像

这样的解决方案
struct Foo {
  #ifdef __cplusplus
  ...
  #else
  ...
  #endif
};

或者反对为不同的编程语言提供不同的API?

答案 2 :(得分:1)

AProgrammer已经给你正确的答案,但问题的“可能”部分的答案是否定的。在处理完所有预处理程序指令之后才会发生宏扩展,因此任何扩展为#define#ifdef的宏都将作为常规源文本传递给编译器,这将导致编译器牦牛。

答案 3 :(得分:0)

我的英语很差,如果有语言错误和错别字,我很抱歉。

如果#ifdef不能包装宏调用,那么解决方案就不那么优雅了。

仅限g ++: 你可以在有选择的场合尝试这个。但是如果a或b中有逗号,则仍需要解决方法。 它只是基于这样一个事实:__ cplusplus在C ++环境中定义为“1”,而在没有的情况下则保持不变。

#define SELECT1(a, b) a
#define SELECT__cplusplus(a, b) b
#define xcat(a,b)  a##b
#define concat(...) xcat(__VA_ARGS__)
#define C_OR_CPP(C, CPP) concat(SELECT, __cplusplus)(C, CPP)

C_OR_CPP(1, 2)

其他环境 检查__cplusplus宏,一个符合标准C ++的编译器应生成

 #define __cplusplus value 

和值应该> = 199711L