const value vs.#define,将使用哪种芯片资源?
如果在嵌入式系统中定义宏或使用静态常量值,const value vs.#define,将使用哪种芯片资源?,c,embedded,C,Embedded,如果在嵌入式系统中定义宏或使用静态常量值, 将使用哪种内存,芯片闪存还是芯片ram? 哪种方法更好?好吧,如果你定义一个宏,就不需要为它分配额外的内存或代码空间(flash)。所有工作都在编译阶段完成 如果使用静态常量全局变量,将为初始值生成二进制代码并为其分配内存。使用闪存(bin文件大小更大)和内存(芯片ram)。我认为答案更复杂 编辑:我为使用“应该”和“可能”道歉,但没有特定的编译器或调试器,我发现它必须准确无误。也许如果这个问题能说明编译器和平台的目标是什么,我们就能更清楚了 #定义名
将使用哪种内存,芯片闪存还是芯片ram? 哪种方法更好?好吧,如果你定义一个宏,就不需要为它分配额外的内存或代码空间(flash)。所有工作都在编译阶段完成
如果使用
静态常量
全局变量,将为初始值生成二进制代码并为其分配内存。使用闪存(bin文件大小更大)和内存(芯片ram)。我认为答案更复杂
编辑:我为使用“应该”和“可能”道歉,但没有特定的编译器或调试器,我发现它必须准确无误。也许如果这个问题能说明编译器和平台的目标是什么,我们就能更清楚了
#定义名称((类型转换)值)
在它出现在代码中之前不会占用任何空间。编译器可能能够使用其值(与使用具有未知运行时值的变量相比)来推断某些内容,因此可能会更改生成的代码,从而使其有效地不占用空间,甚至可能会减少代码的大小。如果编译器的分析是在运行时需要文本值,那么它会占用代码空间。文字值是已知的,因此编译器应该能够分配最佳的空间量。根据处理器的不同,它应该存储在闪存中,但可能不是在线代码,而是存储在“文字池”中,一组局部变量,通常靠近代码,因此可以使用紧凑的地址。编译器可能会做出正确的决定static const type name=value代码>在代码中使用之前不应占用空间。即使在代码中使用它,它也可能会或可能不会消耗“空间”,这取决于编译器(以及,我认为,它正在编译的C标准)和代码如何使用该值
如果从未获取名称的地址,则编译器不必存储该地址。如果取了值的地址(且该代码未消除),则该值必须在内存中。智能编译器将检测源文件中是否有任何代码使用其地址。即使它可能被存储,编译器也可以通过不使用存储值生成更好的(更快或更紧凑的代码)
编译器的工作可能与#define NAME
一样好,尽管可能比#define
差
如果该值的地址已被获取,则编译器将该变量视为初始化变量,这会消耗存储常量值的空间。编译器并没有真正将值放入RAM或闪存中。这取决于链接器。在gcc中,有一些“属性”可以用来告诉链接器将变量放入哪个段。默认情况下,编译器将初始化变量放入默认数据段,并将初始化的const
放入只读段。通过使用属性,程序员可以将变量放入任何段中。使用工具链中通常附带的适当链接器脚本,可以将片段放入flash中。Gcc对文本字符串等数据使用只读数据段
name
应该在调试器中可用,但#define name
将不可用
#define constants
一样对待它们,尽管它们没有那么灵活,因为它们是int
size(IIRC)。无法获取枚举值的地址,因此编译器有尽可能多的选项来生成好的代码和定义名称。它们通常在调试器中可用const type name=value代码>可能会消耗RAM。它必须在内存中,因为编译器无法知道不同文件中的代码是否使用它,或者获取其地址(但gcc LTO可能会改变),因此const
告诉编译器在任何代码试图使用赋值操作符更改值(例如,g)的情况下,发出警告(或“错误”)。通常,RAM中保存的变量存储在数据或bss内存段中。默认情况下,gcc将const
放入只读段,该段可以使用命令行选项-mrodata=
只读数据段进行设置。那部分是手臂上的罗达
const
或not)也保存在闪存中,并在程序启动时(在调用main()
之前)复制到RAM中。在调用main()
之前,所有未初始化的全局或静态变量都设置为0
编译器可能会将
const
变量放入它们自己的内存段(gcc-does),这可能会允许链接器(如ld)脚本将它们放入闪存中,而不会为它们分配任何RAM(这在使用不同指令从闪存加载数据的AVR ATmega上不起作用) 除了其他人所说的以外:
与任何其他值一样,它将在程序运行期间存在于RAM中,也可能存在于可执行文件中。您的意思是“#定义一个宏”吗?请记住,这个决定不仅仅是使用哪种资源……类型检查,遵循范围规则。有关更多讨论,请参阅。对不起,哪个“可能”?我把“可能”改为“应该”,因为“可能”是错误的。