首页 > 解决方案 > 多个结构,需要在一个方法中访问的相同字段

问题描述

我目前尝试用 C 编写一些 lil 文字控制台游戏以获得乐趣。

为此,我需要能够在......好吧...... C中打印类似窗口的结构。

我想使用通用渲染方法(让我们称之为frame_render(...))来渲染所有不同的“ui元素”

现在的问题是:如何解决这个问题?

给定场景:

// Theoretical base
struct frame { int x; int y; int width; int height; }
struct button { int x; int y; int width; int height; ... }
struct whatever { int x; int y; int width; int height; ... }

我怎样才能确保我xy,widthheight总是在正确的记忆点?一开始就“只是”将它们按相同的顺序排列就足够了吗?

另外,如何设计方法头来接受它?

标签: cstructgeneric-programming

解决方案


如果所有结构都以相同类型的成员开头,以相同的顺序,对应的成员将具有相同的偏移量。大多数编译器可以配置为允许使用任何结构类型的指针来检查任何其他的通用初始序列的成员,但有一些问题:

  1. 在一些不寻常的平台上,如果一个对象后跟填充字节,则将对象和填充字节一起写入的指令(可能在后者中存储无意义的值)可能比只写入对象的指令更快。如果一个成员在某些结构中后跟一个填充字节,但在另一个结构中是有意义的数据,则使用其后跟填充字节的类型对该成员的写入可能会用无意义的值覆盖“填充字节”,从而破坏值其他结构类型中的以下成员。我不知道当前使用的任何体系结构对于位域以外的任何结构成员来说都是一个问题,并且我不知道任何当前的实现即使对那些来说这也是一个问题,但是在某些平台上可能会出现这种可能性,

  2. 给定类似的东西:

    int readField1OfS1(struct s1 *p) { return p->field1; }
    
    struct s2 *myStruct2Ptr;
    
    if (readField1ofS1((struct s1*)myStruct2Ptr)
       ...
    

    某些编译器(如 gcc 和 clang)不会可靠地允许从函数返回的值可能取决于struct s2调用时类型对象的部分通用初始序列所持有的值,除非禁用优化(例如使用-fno-strict-aliasing选项)。我认为在函数调用表达式中存在从struct s2*to的转换struct s1*应该允许质量编译器识别任何函数可能对类型对象执行某些struct s1操作可能在 a 上完成struct s2,但由于标准没有明确要求, gcc 和 clang 的作者拒绝做出任何努力来可靠地识别此类构造,即使在上述简单的情况下也是如此。

使用通用初始序列规则的代码几乎可以在任何经过​​适当配置的编译器上可靠地工作,但是像gcc 和 clang 这样的代码必须使用-fno-strict-aliasing选项进行特殊配置. 自 1974 年以来,利用通用初始序列保证的能力一直是该语言的成熟部分,并且在编写该标准时,任何熟悉该语言的人都会理解它旨在允许像上面那样的构造,编译器应该不难识别。然而,由于标准的作者没有明确要求以有用的方式兑现 CIS 保证,clang 和 gcc 的作者决定他们宁愿声称依赖于数十年历史的 CIS 保证的程序是“损坏的”,而不是纪念 40 多年的先例。


推荐阅读