Search code examples
c++preprocessor

redefining a macro not working as expected


I am in C++ defining blocks that go in a special area of memory. I want to define a block, then define the address of the next block in a variable that gets redefined for each block.

#include <iostream>

using namespace std;

#define BASE_ADDRESS 0X1000

// type a gets 100 bytes
#define TYPE_A BASE_ADDRESS
#define NEXT_FREE_BLOCK (BASE_ADDRESS + 100)
    
// type b gets 200 bytes, starting at the next free address
#define TYPE_B NEXT_FREE_BLOCK
#undef NEXT_FREE_BLOCK
#define NEXT_FREE_BLOCK (TYPE_B + 200)

// ---end of RWW memory map---

int main()
{
    cout<<"Hello free block " << NEXT_FREE_BLOCK << endl;
    return 0;
}

Example code that I've looked up looks like this. But when I try to compile this, I get "compilation failed due to the following errors":

main.cpp:12:16: error: ‘NEXT_FREE_BLOCK’ was not declared in this scope
 #define TYPE_B NEXT_FREE_BLOCK
                ^
main.cpp:14:26: note: in expansion of macro ‘TYPE_B’
 #define NEXT_FREE_BLOCK (TYPE_B + 200)
                          ^~~~~~
main.cpp:20:34: note: in expansion of macro ‘NEXT_FREE_BLOCK’
     cout<<"Hello free block " << NEXT_FREE_BLOCK << endl;

                                  ^~~~~~~~~~~~~~~

If I comment out the 'type b' lines, it runs as expected. If I comment out the #undef line, it tells me I've redefined the macro. I would like to redefine the macro without getting an error or warning; is there a way to do that?


Solution

  • Lets take a look at this example:

    #define MYMACRO 0 //MYMACRO = 0
    #define ANOTHERMACRO MYMACRO //ANOTHERMACRO = MYMACRO = 0
    
    int main() {
        return ANOTHERMACRO;
    }
    

    All good right?

    But if we do this:

    #define MYRECURSIVEMACRO 0 //MYRECURSIVEMACRO = 0
    
    #define MYMACRO MYRECURSIVEMACRO //MYMACRO = MYRECURSIVEMACRO
    
    #undef MYRECURSIVEMACRO // MYRECURSIVEMACRO does not exist
    #define MYRECURSIVEMACRO (MYMACRO+10) //What was MYMACRO again? It was MYRECURSIVEMACRO, but now we are setting MYRECURSIVEMACRO, which right now is being defined, to itself plus 10, and now I am 100% confused
    
    #define ANOTHERMACRO MYRECURSIVEMACRO //Now what?
    
    int main() {
        return ANOTHERMACRO;
    }
    

    We get this:

    1>C:\dev\Stack Overflow\Source.cpp(520,9): error C2065: 'MYMACRO': undeclared identifier
    

    (At least for MSVC++)

    Now if we look at this:

    
    #define BASE_ADDRESS 0X1000 //BASE_ADDRESS = 0x1000
    
    // type a gets 100 bytes
    #define TYPE_A BASE_ADDRESS //TYPE_A = BASE_ADDRESS = 0x1000
    #define NEXT_FREE_BLOCK (BASE_ADDRESS + 100) //NEXT_FREE_BLOCK = 0x1000 + 100
        
    // type b gets 200 bytes, starting at the next free address
    #define TYPE_B NEXT_FREE_BLOCK //TYPE_B = NEXT_FREE_BLOCK
    #undef NEXT_FREE_BLOCK //NEXT_FREE_BLOCK is gone
    #define NEXT_FREE_BLOCK (TYPE_B + 200) //Now what? Same problem as before!
    
    // ---end of RWW memory map---
    
    

    This is why it isn't working.