【问题标题】:redefining a macro not working as expected重新定义宏不能按预期工作
【发布时间】:2021-05-28 14:22:10
【问题描述】:

我在 C++ 中定义进入特殊内存区域的块。我想定义一个块,然后在为每个块重新定义的变量中定义下一个块的地址。

#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;
}

我查找的示例代码如下所示。但是当我尝试编译它时,我得到“由于以下错误而导致编译失败”:

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;

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

如果我注释掉“type b”行,它会按预期运行。如果我注释掉#undef 行,它告诉我我已经重新定义了宏。我想重新定义宏而不会收到错误或警告;有没有办法做到这一点?

【问题讨论】:

  • 宏不允许递归,如果它们允许你将有无限递归。
  • 您是否考虑过使用自定义链接器脚本?这些通常让您定义内存部分的名称以及放置它们的位置。在我的脑海中,这听起来有点像你想要实现的目标。
  • enum 可能是一个更简单的解决方案。
  • 您介意解释一下您打算如何使用NEXT_FREE_BLOCK吗?那里可能有一个更优雅的解决方案,但有点不清楚你想要实现什么。
  • 想象更多像问题中所示的类型 b 的情况——我定义了许多块,它们都进入这个特殊的内存区域。最有可能改变的是每个人使用的结构的大小和存储的该结构的元素数量。它还将这些从页面边界开始存储。所以我希望编译器或预处理器根据我给它的大小计算下一个块的地址,而不是每次都手动重新计算它。这就是这里用“base_address + 100”和“type_b + 200”表示的。

标签: c++ preprocessor


【解决方案1】:

让我们看一下这个例子:

#define MYMACRO 0 //MYMACRO = 0
#define ANOTHERMACRO MYMACRO //ANOTHERMACRO = MYMACRO = 0

int main() {
    return ANOTHERMACRO;
}

没事吧?

但如果我们这样做:

#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;
}

我们得到这个:

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

(至少对于 MSVC++)

现在我们看看这个:


#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---

这就是它不起作用的原因。

【讨论】:

  • 我终于弄明白了;这是我问题的实际答案。只是说“枚举”不是解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 2013-05-28
相关资源
最近更新 更多