C ++条件宏评估

时间:2009-03-26 18:48:41

标签: c++ gcc macros c-preprocessor

我有一个全局定义的符号,需要对我的源文件的给定子集有条件地定义。所有需要特殊处理的文件都已经包含在包含前后:

pre.h:

#undefine mysymbol // [1]

post.h:

#define mysymbol MY_SYMBOL_DEFINITION // [2]

我的问题是,由于各种包含链接,对于给定的源文件,pre.hpost.h可以多次包含。因此,我需要在第一次包含pre.h时发生1,我需要2才能发生上次 post.h。从概念上讲:

pre         // undefine
   pre      // no-op
      pre   // no-op
      post  // no-op
   post     // no-op
post        // redefine

由于我使用的是GCC 3.4.6,因此我无权访问可能以其他方式解决此问题的push and pop macro pragmas

如何使用剩余的预处理器功能模拟该行为?

我试图用预处理器来增加/减少一个值,但我不确定这是可能的。

“我到底想做什么?”

我们有用new代替new(__FILE__, __LINE__)的宏 - 请参阅my other question on this topic - 我们需要在前后包装的源文件集中取消定义这些宏包括上面描述的因为我们无法创建与其中使用的放置新语法兼容的宏。

5 个答案:

答案 0 :(得分:4)

您可以在pre.h文件中添加以下内容:

... 

#ifdef COUNT
#if COUNT == 2
#undef COUNT
#define COUNT 3
#endif

#if COUNT == 1
#undef COUNT
#define COUNT 2
#endif

#else
#define COUNT 1

... here put your pre.h code

#endif

在post.h中:

#ifdef COUNT
#if COUNT == 1
#undef COUNT
#endif

#if COUNT == 2
#undef COUNT
#define COUNT 1
#endif

#if COUNT == 3
#undef COUNT
#define COUNT 2
#endif

...    

#end

#ifndef COUNT

... here put your pre.h code

#endif

但是你需要知道你能走多远。

答案 1 :(得分:0)

在编程时增加/减少值可能是元编程魔法a-la Loki。但你确定这是必要的吗?

为什么你的h文件包含这么多时间?为什么不使用包含警卫?

答案 2 :(得分:0)

尝试:

文件pre.h

#ifndef MYMACROGUARD
    #undef MYMACRO
    #define MYMACROGUARD MYMACROGUARD+1
#endif

File post.h

#if MYMACROGUARD <= 0
    #undef MYMACROGUARD
#else
    #define MYMACROGUARD MYMACROGUARD-1
#endif

使用此代码进行测试

#define MYMACRO

#include<iostream>

using namespace std;
int main()
{
    #ifdef MYMACRO
        cout<<"1"<<endl;
    #endif

    #include <pre.h>

    #ifdef MYMACRO
        cout<<"2"<<endl;
    #endif

    #include <pre.h>

    #ifdef MYMACRO
        cout<<"3"<<endl;
    #endif

    #include <post.h>

    #ifdef MYMACRO
        cout<<"4"<<endl;
    #endif

    #include <post.h>

    #ifdef MYMACRO
        cout<<"5"<<endl;
    #endif
}

$> g++ -w -I. test.cpp && ./a.out

1
5

答案 3 :(得分:0)

如果您知道最大递归深度,那么您应该能够通过在每个级别定义一个新宏来模拟推/弹。对于您给出的3级示例,它看起来像:

<强> Pre.h:

#ifdef RECURSION_COUNT_1
 #ifdef RECURSION_COUNT_2
  #ifdef RECURSION_COUNT_3
   #error Recursion level too deep
  #else
   #define RECURSION_COUNT_3
  #endif
 #else
  #define RECURSION_COUNT_2
 #endif
#else
 #define RECURSION_COUNT_1
 #undef YOUR_SYMBOL_HERE
#endif

<强> Post.h

#ifdef RECURSION_COUNT_3
 #undef RECURSION_COUNT_3
#else
 #ifdef RECURSION_COUNT_2
  #undef RECURSION_COUNT_2
 #else
  #ifdef RECURSION_COUNT_1
   #undef RECURSION_COUNT_1
   #define YOUR_SYMBOL_HERE
  #endif
 #endif
#endif

答案 4 :(得分:0)

pre.h

#ifndef MYSYMBOLUNDEFFERSTACK
#define MYSYMBOLUNDEFFERSTACK 0
#else
#define MYSYMBOLUNDEFFERSTACKTMP (MYSYMBOLUNDEFFERSTACK+1)
#undef MYSYMBOLUNDEFFERSTACK
#define MYSYMBOLUNDEFFERSTACK MYSYMBOLUNDEFFERSTACKTMP
#undef MYSYMBOLUNDEFFERSTACKTMP
#endif

#if MYSYMBOLUNDEFFERSTACK == 0
#undef mysymbol
#endif

post.h

#ifndef MYSYMBOLUNDEFFERSTACK
#error "Async Post.h"
#else
#define MYSYMBOLUNDEFFERSTACKTMP (MYSYMBOLUNDEFFERSTACK-1)
#undef MYSYMBOLUNDEFFERSTACK
#define MYSYMBOLUNDEFFERSTACK MYSYMBOLUNDEFFERSTACKTMP
#undef MYSYMBOLUNDEFFERSTACKTMP
#endif

#if MYSYMBOLUNDEFFERSTACK == 0
#define mysymbol "MY_SYMBOL_DEFINITION"
#endif

在这种情况下哪种方法正常:

#include "stdio.h"
#include "pre.h"
#include "pre.h"
#include "pre.h"
//const char *pCompileError = mysymbol;
#include "post.h"
//const char *pCompileError = mysymbol;
#include "post.h"
//const char *pCompileError = mysymbol;
#include "post.h"

int main(void)
{
    const char *p = mysymbol;
    printf("%s\n", p);
    return 0;
}

编辑: 适用于gcc 4.0。