在调用另一个宏后不断增加宏的值

标签 c macros c-preprocessor armcc

我正在编写一个带有结构化模式的头文件。我的目标是定义一个基地址,该地址将在调用另一个宏后递增。这样做的目的是保持新基地址的运行计数,并在编译时检查它是否超过最大物理地址。

我以前想过使用一个全局变量来计算地址,但这会在运行时解决,我在编译时需要这个,在输出任何二进制文件之前,以防止可能的内存损坏。

下面是我的意思:

以下是我希望头文件在检查时看起来也像(或类似的东西):

#define DRAM_DEFINE_PTR              0x30000000
#define DRAM_DATA1_BASE              0x30000100
#define DRAM_DATA1_SIZE              0x050
#define DRAM_DATA2_SIZE              0x400
#define DRAM_DATA3_BASE              0x30000600
#define DRAM_DATA3_SIZE              0x300

#define DRAM_DEFINES(x,y)            (...) 
// store base 'x' and size 'y' in a structure and increment DRAM_DEFINE_PTR accordingly

1.     DRAM_DEFINES (DRAM_DATA1_BASE,        DRAM_DATA1_SIZE)
2.     DRAM_DEFINES (0x0,                    DRAM_DATA2_SIZE)   //base is previous base + size
3.     DRAM_DEFINES (DRAM_DATA3_BASE,        DRAM_DATA3_SIZE)
// more DRAM_DEFINES

实际上,下面的代码块会将第 1 行和第 2 行展开为:

1.     DRAM_DEFINES (0x30000100,        0x50)
       // DRAM_DEFINE_PTR now equals 0x30000150

2.     DRAM_DEFINES (0x30000150, 0x400)
       // DRAM_DEFINE_PTR now equals 0x30000550

3.     DRAM_DEFINES (0x30000600 , 0x300)
       // DRAM_DEFINE_PTR now equals 0x30000900
and so on

然后在文件末尾进行#error 检查以确保我们没有越界

#if (DRAM_DEFINE_PTR > 0x40000000)
   #error "\nCAPACITY EXCEEDED by ", DRAM_DEFINE_PTR - 0x40000000, " bytes"
#endif

从上面我们可以看出,并不是每个内存区域都要被完全使用。就像 2 和 3 之间有 50 个字节的缓冲区。所以这意味着基地址可以是

  • 使用#define OR 硬编码值
  • 从前一个区域的基数偏移 + 前一个区域的大小

这在我使用的编译器 (ARMCC RVCT 5.03) 中是否可行?

提前致谢

最佳答案

您可以在使用 Boost 预处理器库的 evaluated slots functionality 翻译一个单元的过程中更新宏的值.它定义了几个可以被预处理器代码视为可变全局变量的“插槽”,这将使您可以在进行时添加一个值,而不是用一个固定的表达式永久地定义它。它是纯标准兼容的 C(或 C++)。

主要的语法麻烦是你必须给更新操作本身两行,因为它由 #define/#include 对提供支持。

#define DRAM_PTR_SLOT 2    // any slot
#define DRAM_DEFINE_PTR BOOST_PP_SLOT(DRAM_PTR_SLOT)
#define SET_DRAM_DEFINE_PTR BOOST_PP_ASSIGN_SLOT(DRAM_PTR_SLOT)

#define BOOST_PP_VALUE 0x30000100 + 0x50
#include SET_DRAM_DEFINE_PTR    // DRAM_DEFINE_PTR now evals to 0x30000150

#define BOOST_PP_VALUE DRAM_DEFINE_PTR + 0x50
#include SET_DRAM_DEFINE_PTR    // DRAM_DEFINE_PTR now evals to 0x300001A0

它不是非常优雅 - 没有办法将指令打包到另一个宏中,所以你不能将它隐藏在问题中的语法中 - 但你至少可以将 Boost 名称隐藏在一些您自己的特定于域的包装器宏。

关于在调用另一个宏后不断增加宏的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26170698/

相关文章:

C++ __COUNTER__ 定义

c - 查找两个日期之间的差异 C

C++宏仅在预处理为文件时有效

c - 这个宏包装展示了什么概念?

c++ - C/C++ 可以在宏中使用 "for loop"而不是 "do while"吗?

c++ - 在 C++ 中使用#define 宏从不同的命名空间中选择实现

c++ - C++ 上的预处理器重载

cntlm 错误 : Too many open files

c - 发生错误,我该如何修复它?

c++ - 如何同时等待 I/O 完成端口和事件?