嵌入式 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)
通过了解 func1
、func2
和 func3
是来自不同 .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 变量具有强类型和作用域。
我知道 C 中的宏,例如:
#define VARNULL (u8)0
不把这个VARNULL
存入RAM,但这当然会增加FLASH中的代码量。
但是如果我有一个多行宏怎么办,例如:
#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0)
通过了解 func1
、func2
和 func3
是来自不同 .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 变量具有强类型和作用域。