嵌入式 C 中的宏如何影响内存?

How macros in embedded C affect memory?

我知道 C 中的宏,例如:

#define VARNULL (u8)0

不把这个VARNULL存入RAM,但这当然会增加FLASH中的代码量。

但是如果我有一个多行宏怎么办,例如:

#define CALL_FUNCS(x) \
do { \
  func1(x); \
  func2(x); \
  func3(x); \
} while (0)

通过了解 func1func2func3 是来自不同 .c 文件的函数。这是否意味着这些功能将存储在 RAM 中?当然还有 FLASH(代码)。

如有错误请指正?

你一直说 "of course" 宏将 "stored" 在目标设备的闪存中,但事实并非如此。

宏在源代码中存在;它们在编译期间被替换为它们定义的值。闪存中的程序不会以任何有意义的方式"contain"它们。

宏和任何其他前缀为 # 的指令在 C 编译之前由预处理器处理;它们不生成任何代码,而是生成 源代码 然后由编译器处理,就像您直接输入代码一样。所以在你的例子中代码:

int main()
{
    CALL_FUNCS(2) ;
}

生成以下源代码的结果:

int main()
{
    do { \
      func1(2);
      func2(2);
      func3(2);
    } while (0) ;
}

就这么简单。如果您从不调用宏,它就不会生成任何代码。如果多次调用它,它将多次生成代码。宏没有什么聪明的地方,只是在 编译之前生成的文本替换;编译器用它做什么完全取决于宏扩展到什么,而不是它是一个宏这一事实——编译器只看到生成的代码,而不是宏定义。

关于const vs #define,文字常量宏也是jyst的文本替换,将作为文字常量放在代码中。另一方面,const 是一个 变量 。编译器可能会简单地插入一个文字常量,从而生成更少的从内存中获取常量的代码,在 C++ 中保证简单类型​​,并且 C 编译器不以相同的方式运行是不寻常的。但是,因为它是一个变量,所以您可以获取它的地址 - 如果您的代码确实获取了 const 的地址,那么 const 必然具有存储空间。该存储是在 RAM 还是 ROM 中取决于您的编译器和链接器配置 - 您应该查阅工具链文档以了解它如何处理常量存储。

使用 const 的一个好处是,与宏不同,const 变量具有强类型和作用域。