C 内存空间和#defines
我正在开发嵌入式系统,因此内存对我来说很珍贵。
一个反复出现的问题是,当我尝试为其编译程序时,内存空间不足。这通常可以通过限制可能占用大量空间的 typedef 的数量来解决。
有一个宏生成器,我用它来创建一个包含大量 #define 的文件。 其中一些是简单值,其他是边界检查,
即
#define SIGNAL1 (float)0.03f
#define SIGNAL1_ISVALID(value) ((value >= 0.0f) && (value <= 10.0f))
现在,我不使用所有这些定义。我使用了一些,但实际上不是大多数。 有人告诉我,如果不使用它们,它们实际上不会占用任何内存,但我对此不确定。我希望通过删除未使用的内存可以释放一些额外的内存(但我再次被告知这是毫无意义的)。
未使用的#define 会占用任何内存空间吗?
I am working on an embedded system, so memory is precious for me.
One issue that has been recurring is that I've been running out of memory space when attempting to compile a program for it. This is usually fixed by limiting the number of typedefs, etc that can take up a lot of space.
There is a macro generator that I use to create a file with a lot of #define's in it.
Some of these are simple values, others are boundary checks
ie
#define SIGNAL1 (float)0.03f
#define SIGNAL1_ISVALID(value) ((value >= 0.0f) && (value <= 10.0f))
Now, I don't use all of these defines. I use some, but not actually the majority.
I have been told that they don't actually take up any memory if they are not used, but I was unsure on this point. I'm hoping that by cutting out the unused ones that I can free up some extra memory (but again, I was told this is pointless).
Do unused #define's take up any memory space?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,#defines 除非使用,否则不会占用空间 - #defines 的工作方式类似于查找/替换;每当编译器看到左半部分时,它都会在实际编译之前将其替换为右半部分。
因此,如果您有:
编译器将按字面解释该语句:
它将永远看到SIGNAL1,它不会显示在调试器等中。
No, #defines take up no space unless they are used - #defines work like find/replace; whenever the compiler sees the left half, it'll replace it with the right half before it actually compiles.
So, if you have:
The compiler will literally interpret the statement:
It will never see the SIGNAL1, it won't show up in a debugger, etc.
您似乎有些困惑,因为 typedef 在运行时不占用空间。它们只是数据类型的别名。现在您可能拥有大型结构的实例(类型定义或其他),但占用空间的是实例,而不是类型定义。我想知道这个声明中可能涵盖什么“等”。
宏实例在源代码中被替换为它们的定义,并相应地生成代码,未使用的宏不会生成任何生成的代码。
占用空间的东西有:
剩下的通常可用于动态内存分配 (RAM),或者未使用或用于非易失性存储 (闪存/EPROM)。
减少内存使用主要是选择/设计高效的数据结构、使用适当的数据类型以及高效的代码和算法设计。最好瞄准能获得最大利益的领域。要查看应用程序中对象和代码的大小,请让链接器生成映射文件。这将告诉您哪些是最大的函数,以及全局对象和静态对象的大小。
源文件文本长度并不能很好地指导代码大小。大量的C代码是声明性的(一般头文件都是声明性的),并且不会生成占用内存的代码或数据。
嵌入式系统并不一定意味着内存较小,因此您应该指定。我曾经使用过具有 64Mb RAM 和 2Mb 闪存的系统,但与许多系统相比,这也算不上什么了。然而,具有片上资源的典型微控制器通常会少得多(特别是占用大量芯片面积的 SRAM)。此外,无论您的系统是哈佛架构还是冯诺依曼架构,都与此相关,因为在哈佛架构中,数据和代码空间是分开的,所以我们需要知道您缺少什么。如果是冯·诺依曼,如果代码是从 ROM 运行,或者是在运行时从 ROM 复制到 RAM(即不同类型的内存,即使它们位于同一地址空间),则代码/数据的使用仍然相关。
克利福德
You seem somewhat confused because typedef's do not take up space at runtime. They are merely aliases for data types. Now you may have instances of large structures (typedef'd or otherwise), but it is the instance that takes space, not the type definition. I wonder what 'etc' might cover in this statement.
Macro instances are replaced in the source code with their definition, and code generated accordingly, an unused macro does not result in any generated code.
Things that take up space are:
What is left is typically available for dynamic memory allocation (RAM), or is unused or made for non-volatile storage (Flash/EPROM).
Reducing memory usage is primarily a case of selecting/designing efficient data structures, using appropriate data types, and efficient code and algorithm design. It is best to target the area that will get the greatest benefit. To see the size of objects and code in your application, get the linker to generate a map file. That will tell you which are the largest functions, as well as the sizes of global and static objects.
Source file text length is not a good guide to code size. Large amounts of C code is declarative (typically header files are all declarative), and do not generate memory occupying code or data.
An embedded system does not necessarily imply small memory, so you should specify. I have worked on systems with 64Mb RAM and 2Mb Flash, and even that is modest compared with many systems. A typical micro-controller with on-chip resources however, will generally have much less (especially SRAM which takes up a lot of chip area). Also whether your system is Harvard or Von Neumann architecture is relevant here, since in a Harvard architecture data and code spaces are separate, so we need to know what it is you are short of. If Von Neumann, the code/data usage is still relevant if the code is running from ROM, or is it is copied from ROM to RAM at run-time (i.e. different types of memory, even if they are in the same address space).
Clifford
嗯,是的,也不是。
不,未使用的 #defines 不会增加生成的二进制文件的大小。
是的,编译器在构建二进制文件时必须知道所有 #define(无论是否使用)。
根据您的问题,您如何使用编译器有点不明确,但似乎您尝试直接在嵌入式设备上构建;你尝试过交叉编译器吗? :)
Well, yes and no.
No, unused #defines won't increase the size of the resulting binary.
Yes, all #defines (whether used or unused) must be known by the compiler when building the binary.
By your question it's a bit ambiguous how you use the compiler, but it almost seems that you try to build directly on an embedded device; have you tried a cross-compiler? :)
未使用的#defines 不会占用生成的可执行文件中的空间。它们在编译时确实会占用编译器本身的内存。
unused #defines doesn't take up space in the resulting executable. They do take up memory in the compiler itself whist compiling.