【发布时间】:2018-05-14 09:22:52
【问题描述】:
有些架构有多个地址空间,值得注意的例子是真正的哈佛架构,但例如 OpenCL 也有这个属性。
C 编译器可能会为此提供一些解决方案,其中之一是命名地址空间,支持特殊的指针限定符来指示指针的地址空间,但也可能存在其他解决方案。
- 对于 GCC,对应的文档在这里:https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Named-Address-Spaces.html
- 对于针对 AVR 的 IAR,相应的文档在此处:https://www.iar.com/support/tech-notes/compiler/strings-with-iccavr-2.x/(请注意,这早于 GCC 的支持,GCC 可能针对 8 位 AVR 目标进行了调整)。
- 对于 SDCC(小型设备 C 编译器):http://sdcc.sourceforge.net/doc/sdccman.pdf,从第 36 页开始。涵盖 8051、Z80 和 68HC08 等微控制器。
- OpenCL 的一些信息:https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/local.html 和 https://software.intel.com/en-us/articles/the-generic-address-space-in-opencl-20
我不知道它们,并且在我使用的体系结构(8 位 AVR)上,还有另一种解决该问题的解决方案,专门的宏 (pgmspace.h) 来处理 ROM 中的数据。但是对这些没有类型检查,并且它们(在我看来)使代码变得丑陋,所以在我看来,使用命名地址空间是一种更好的,甚至可能更便携的方式来处理问题(在那个方面是便携的)通过为地址空间限定符提供空定义,可以轻松地将此类软件移植到具有单个地址空间的目标。
但是在我从它们的可用性中了解到的上一个问题中,建议使用命名地址空间的解决方案被严重否决,这里:How to make two otherwise identical pointer types incompatible
downvoters 没有提供任何解释,我自己也没有找到任何解释,对我来说,命名地址空间似乎是处理问题的一种很好且功能完善的方法。
谁能解释一下?为什么可能不应该使用命名地址空间? (偏向于具有多个不同地址空间的目标上可用的任何其他方法)
【问题讨论】:
-
我不是反对者之一,但 C 社区经常坚持可移植性。根据定义,命名地址空间是特定于某些实现的,不能广泛移植。恕我直言,当您需要区分 RAM 与 ROM 时,它仍然是合适的工具。顺便说一句,标准 C 没有 RAM/ROM 的概念......
-
@SergeBallesta 我明白了,但是如果目标有这个限制(没有通用指针),则必须提供一些特定于平台的方法,并且程序员必须使用它。在那个特定的问题上,高度评价的结构既不能解决这部分问题,但可以肯定的是,如果做得好,它们可以成为一种包含它的方法。出于这个原因,我在上面也提到了命名地址空间的可移植性,例如,在 AVR 的情况下,只需在公共标头中添加
#define __flash即可消除区别。 -
我认为有几个缺点:a) 最糟糕的,目标依赖。我们正在创建一个更难移植的代码,没有适当的理由。 b) 要创建一个漂亮且定义明确的内存映射,我们可以使用链接器,它对每个人来说更标准且易于理解。 c) 代码规则和编译器。我们将不得不添加大量可能隐藏实际问题的类型转换。出于测试目的,通常使用两个编译器(比如说 AVR 和 Intel)。 d) 您可以使用“#ifdef __flash”,但如果不是-def,您将无法获得所需的内存映射。
-
@JoseFelipe 我认为您并不真正了解命名地址空间在哪里可用。要点是在这样的架构上,它需要不同的二进制代码(不同的指令)来访问不同的地址空间。您不能在指向不同地址空间的指针之间进行类型转换! (编译器会抛出一个错误)它并不是用来控制内存映射的工具(不仅仅是地址空间本身所暗示的)。在 AVR 上,IAR 也具有相同的命名地址空间支持。
-
@Jubatian 正如你所读到的,我说的是几个编译器的使用。如果您的编译器不包含 named-address-spaces 关键字,则必须解决它。取决于编译器而不使用链接器(从我的角度来看这是正确的解决方案),解决方案只能是 ram(const 不能确保使用 flash)。
标签: c pointers memory-address