5

我有一个全局定义的符号,需要为我的源文件的给定子集有条件地未定义。所有需要特殊处理的文件都已经包含在 pre-inclusions 和 post-inclusions 中:

前.h:

#undefine mysymbol // [1]

post.h:

#define mysymbol MY_SYMBOL_DEFINITION // [2]

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

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

由于我使用的是 GCC 3.4.6,因此我无法访问可能会为我解决此问题的push 和 pop 宏编译指示。

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

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

“我到底想做什么?”

我们有宏要替换new——new(__FILE__, __LINE__)请参阅我关于这个主题的另一个问题——我们需要取消定义由上述前置和后置包含的源文件集中的这些宏,因为我们无法创建一个宏与其中使用的放置新语法兼容。

4

5 回答 5

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

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

于 2009-03-26T19:27:05.803 回答
0

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

为什么你的 h 文件被包含这么多次?为什么不使用包含防护?

于 2009-03-26T19:15:54.737 回答
0

尝试:

文件 pre.h

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

文件 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
于 2009-03-26T19:18:17.040 回答
0

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

前.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
于 2009-03-26T19:22:29.900 回答
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。

于 2009-03-26T19:32:48.957 回答