4

This is originally posted as an answer to c++ macros with memory?

But somehow I am not able to get this compiled. I might be missing something here. (I have a feeling that this is something C++ can do)

main.cpp

#include <iostream>
using namespace std;

const char * hello = "hello";
const char * world = "world";

#define VAR

#define MEMORIZE world
#include "memorize.h"
#define MEMORIZE hello
#include "memorize.h"

int main() {
    cout << VAR << endl;
    return 0;
}

memorize.h

#undef VAR
#ifndef MEMORIZE
    # error "No Argument to memorize.h"
#endif
#define VAR MEMORIZE
#undef MEMORIZE

The compile error that I am getting is this:

[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
error: use of undeclared identifier 'MEMORIZE'
    cout << VAR << endl;
            ^
note: instantiated from:
#define VAR MEMORIZE
            ^
1 error generated.
make[2]: *** [CMakeFiles/main.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2

I really want to get this memory thing to work in preprocessing phase. Can someone help? I think BOOST_PP_COUNTER in 1.49 also uses this technique but i couldn't figure out how.

Community
  • 1
  • 1
Negative Zero
  • 1,224
  • 3
  • 10
  • 19

3 Answers3

1

You are using only a single VAR value (the last one) because it can take only one value. If you want to mean different things by VAR depending on the context, you need to have source statements after each include.

#define xstr(a) str(a)
#define str(a) #a
int main() {
#define MEMORIZE world
#include "memorize.h"
      cout << VAR << endl;
#undef MEMORIZE
#define MEMORIZE hello
#include "memorize.h"
      cout << VAR << endl;
          return 0;
}

memorize.h:

#undef VAR
#ifndef MEMORIZE
    # error "No Argument to memorize.h"
#endif
#define VAR xstr(MEMORIZE)
perreal
  • 94,503
  • 21
  • 155
  • 181
0

You are are setting the VAR macro to the token MEMORIZE, which you are promptly undefining. The line:

cout << VAR << endl;

ends up as:

cout << MEMORIZE << endl;

and since MEMORIZE is undeclared, you get the error. It thinks MEMORIZE is a variable name.

Kendall Frey
  • 43,130
  • 20
  • 110
  • 148
  • Are you suggesting this is not something can be done? I am just wondering how did BOOST_PP_COUNTER works? http://www.boost.org/doc/libs/1_49_0/libs/preprocessor/doc/index.html – Negative Zero Mar 02 '12 at 00:20
  • If it can be done, I have no idea how. A better, simpler, and more standard solution is to define a macro to have a certain value before using it, and you can 'redefine' it anywhere you please. – Kendall Frey Mar 02 '12 at 00:25
  • I looked at the boost source, and (from a possibly inaccurate skim of the code) it looks like they use `if (counter == 0) { counter = 1 } else if (counter == 1) { counter = 2 } ...` style code, except with digit manipulation to enable multidigit numbers with sub-exponential code size. Somewhere there is a programmer with brain damage. – Kendall Frey Mar 02 '12 at 00:41
  • i think it's probably not possible now with just one variable. – Negative Zero Mar 03 '12 at 00:14
0

You need to move the #undef MEMORIZE line -- take it out of memorize.h and put it right before #define MEMORIZE everywhere that appears.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226