首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌入式C++中零大小数组的替代方案

嵌入式C++中零大小数组的替代方案
EN

Stack Overflow用户
提问于 2015-11-02 03:51:43
回答 1查看 673关注 0票数 3

多重引导规范的结构如下所示:

代码语言:javascript
复制
struct multiboot_tag_mmap
{
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint32_t entry_size;
  multiboot_uint32_t entry_version;
  struct multiboot_mmap_entry entries[0];  
};

其意图似乎是数组大小可以改变。在引导加载程序传递信息之前,不知道这些信息。在托管C++中,建议的建议是“使用vector”。我不能那么做。另一种方法是使用动态分配,但这需要实现内核的一个重要部分(分页、MMU等)。在我还没有记忆地图信息之前。有点鸡或蛋的问题。

"hack“只是使用gnu++11启用扩展。但我尽量避免使用扩展,以避免可能导致未定义行为的C代码或代码。在我看来,代码的可移植性越强,出现bug的可能性就越小。

最后,您可以像下面这样迭代内存映射:

代码语言:javascript
复制
for (mmap = ((struct multiboot_tag_mmap *) tag)->entries;
    (multiboot_uint8_t *) mmap
    < (multiboot_uint8_t *) tag + tag->size;
    mmap = (multiboot_memory_map_t *)
    ((unsigned long) mmap
    + ((struct multiboot_tag_mmap *) tag)->entry_size))

所以这个结构的大小是tag->size

只要语义相同,我就可以修改多重引导头。重点在于引导加载器的外观。我能做什么?

EN

回答 1

Stack Overflow用户

发布于 2015-11-02 07:02:54

您可以使用1大小的数组,而不是0大小的数组:

代码语言:javascript
复制
struct multiboot_tag_mmap
{
    ...
    struct multiboot_mmap_entry entries[1]; 
};

这只会改变sizeof(struct multiboot_tag_mmap)的结果,但无论如何都不应该使用:分配的结构的大小应该计算为

代码语言:javascript
复制
offsetof(struct multiboot_tag_mmap, entries) + <num-of-entries> * sizeof(struct multiboot_mmap_entry)

映射结构的对齐不取决于条目数组中的元素数量,而取决于条目类型。

严格确认可选的:如果存在数组大小的已知边界,则可以使用此边界进行类型声明:

代码语言:javascript
复制
struct multiboot_tag_mmap
{
    ...
    struct multiboot_mmap_entry entries[<UPPER-BOUNDARY>]; 
};

对于这种声明,不适用下文所述的所有可能问题。

关于元素访问的注释:用于访问这种灵活数组中的元素(在第一个元素之上)的,需要声明新的指针变量:

代码语言:javascript
复制
struct multiboot_mmap_entry* entries = tag->entries;
entries[index] = ...; // This is OK.

而不是直接使用entries字段:

代码语言:javascript
复制
tag->entries[index] = ...; // WRONG! May spuriously fail!

问题是,编译器知道entries字段数组中只有一个元素,所以可以将最后一种情况优化为:

代码语言:javascript
复制
tag->entries[0] = ...; // Compiler is in its rights to assume index to have the only allowed value

问题有关标准确认:使用灵活的数组方法,内存中(堆或堆栈中)没有struct multiboot_tag_mmap类型的对象。我们所拥有的只是一个这种类型的指针,它永远不会被取消引用(例如,用于创建对象的完整副本)。类似地,没有数组类型struct multiboot_mmap_entry[1]的对象,该对象对应于结构的entries字段,该字段仅用于转换为struct multiboot_mmap_entry*类型的泛型指针。

所以,C标准中的短语,表示未定义的行为

对象被赋值给不完全重叠的对象或完全重叠的不兼容类型的对象。

不适用于使用泛型指针访问entries数组字段:此处不存在重叠对象。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33470473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档