正如标题所说,在FLASH中占用更多空间(例如在STM32μC中)?声明一个全局变量或在函数内声明一个静态变量?或者他们是否占用相同的空间?根据我的理解,这两个变量在整个程序运行时都可用。只是他们的范围不同。
答案 0 :(得分:5)
您可以拥有0初始化的全局变量和静态变量。那些通常不占用闪存,因为它们被放置在内存位置,当程序启动时它被分配并归零,而不是来自闪存。
您也可以使用值初始化变量。在这种情况下,它们被放置在初始化的数据段中,因此根据数据类型的大小从闪存中占用空间。
函数内的静态变量也可以用代码初始化。初始化必须在运行时发生,但只能发生一次,所以它实际上生成了更多的代码,几乎在任何情况下都会占用比数据大小更多的空间(不一定,至少如果你用一个足够大的结构初始化一个足够大的结构)函数返回值)。您也可以对非const全局变量执行几乎相同的操作,您只需要将它们保留为0初始化,并将赋值(例如)放在main()
的开头,其中它与函数初始化占用相同的空间范围内的静态变量取代其他地方。
结论,全局和函数范围的静态变量占用相同的空间量。
上面假设嵌入式上下文中的“全局变量”,或者作为文件范围的静态变量。如果在动态可链接的可执行文件中导出全局符号,则该符号的重定位信息将占用可执行二进制文件中的一些空间。但是,我不认为给定的示例系统支持或使用可重定位的可执行文件。
答案 1 :(得分:1)
“整个运行时可用”的正式术语是静态存储持续时间。在文件范围(“global”)声明的变量以及用static
声明的所有变量都具有静态存储持续时间。
因此范围和存储持续时间之间存在关联:范围可以决定变量的存储持续时间。但是范围和内存使用之间没有关系。
变量占用的空间仅取决于变量类型的大小。范围和存储持续时间与它无关。
在大多数编译器/链接器中,变量最终需要闪存两件事:
const
和如果不满足这些条件,变量将不会以flash / nvm结尾,无论声明的范围是什么。
答案 2 :(得分:0)
正如标题所说,在FLASH中占用更多空间(例如在STM32μC中)?声明一个全局变量或在函数内声明一个静态变量?或者他们是否占用相同的空间?
使用arm-none-eabi-gcc作为STM32构建的参考,根本不占用任何闪存空间。
未声明const
的全局变量和静态变量如果需要启动初始化,则进入.data
部分,如果不需要,则进入.bss
部分。这两个段都由链接描述文件放入SRAM中。如果您正在使用C ++,那么静态C ++类最终会在.bss
。
如果您确实声明了它们const
,那么它们将被放入.rodata
部分,如果您查阅链接器脚本,您应该找到.text
的子部分。闪光灯。 Flash通常比SRAM更丰富,所以尽可能使用const
。
最后,优化器可以出现并完全重新排列它认为合适的任何内容,包括消除内存以支持内联。