Reputation: 43619
I have a symbol defined globally that needs to be conditionally undefined for a given subset of my source files. All of the files that require special treatment are already wrapped in pre- and post-inclusions:
pre.h:
#undefine mysymbol // [1]
post.h:
#define mysymbol MY_SYMBOL_DEFINITION // [2]
My problem is that the pre.h
and post.h
can be included multiple times for a given source file due to various inclusion chaining. As such, I need 1 to happen the first time pre.h is included and I need 2 to happen the last time that post.h
is included. Conceptually:
pre // undefine
pre // no-op
pre // no-op
post // no-op
post // no-op
post // redefine
Since I am using GCC 3.4.6, I do not have access to the push and pop macro pragmas that might otherwise solve this issue for me.
How can I emulate that behavior with the remaining preprocessor functionality?
I was attempting to do something like increment/decrement a value with the preprocessor, but I'm not sure that's possible.
"What am I really trying to do?"
We have macros to replace new
with new(__FILE__, __LINE__)
-- see my other question on this topic -- and we need to undefine those macros in the set of source files wrapped by the pre- and post-includes described above because we were unable to create a macro that's compatible with the placement new syntax used therein.
Upvotes: 5
Views: 9268
Reputation: 12901
Try:
#ifndef MYMACROGUARD
#undef MYMACRO
#define MYMACROGUARD MYMACROGUARD+1
#endif
#if MYMACROGUARD <= 0
#undef MYMACROGUARD
#else
#define MYMACROGUARD MYMACROGUARD-1
#endif
Tested with this code
#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
Upvotes: 0
Reputation: 76103
Incrementing/decrementing a value at compile time is probably possible with meta-programming wizardry a-la Loki. But are you sure this is necessary?
Why is your h file included so many time? Why not use an include guard?
Upvotes: 0
Reputation: 1026
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
Which works fine in this case:
#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;
}
Edit: Works fine with gcc 4.0.
Upvotes: 0
Reputation: 14977
You can add somethig like this to your pre.h file:
...
#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
And in 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
But you need to know how deep can you go.
Upvotes: 4
Reputation:
If you know the maximum depth of recursion, then you should be able to simulate the push/pop by defining a new macro at each level. For the 3 level example you give, that would look something like:
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
Upvotes: 0