多个结构,需要在方法中访问的相同字段

X39*_*X39 0 c struct generic-programming

我目前尝试在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; ... }
Run Code Online (Sandbox Code Playgroud)

我怎么能保证我的x,y,widthheight总是在正确的位置的内存明智?是否足以在刚开始时"正好"将它们放在同一个顺序中?

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

sup*_*cat 5

如果所有结构都以相同类型的成员开头,则按相同的顺序,相应的成员将具有相同的偏移量.大多数编译器都可以配置为允许任何结构类型的指针用于检查任何其他结构类型的Common Initial Sequence的成员,但是存在一些问题:

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

  2. 给出如下内容:

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

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

使用Common Initial Sequence规则的代码几乎可以在任何适当配置的编译器上可靠地工作,但是必须使用-fno-strict-aliasingoption 专门配置gcc和clang等一些代码.自1974年以来,利用通用初始序列保证的能力已经成为该语言中已经确立的一部分,并且当编写标准时,任何熟悉该语言的人都会理解它的设计是为了允许像上面这样的构造,哪些编译器应该没有困难识别.由于该标准的作者没有明确要求CIS保证以有用的方式得到尊重,因此clang和gcc的作者已经决定他们宁愿声称依赖于几十年前的CIS保证的程序比荣誉40多年的先例.

  • @ X39:我认为很明显标准的作者希望它可以工作,并且在实践中只要你确定在需要它的编译器上使用适当的标志就可以工作.我所知道的只有两个编译器需要这样的标志来使用CIS保证是clang和gcc,但有可能还有其他编译器.请注意,clang和gcc绝对不支持没有标志的代码. (2认同)
  • @ x39:编写代码有意义并记录使其工作所需的内容.标准没有尝试完全指定对任何特定目的有用的语言,并且由clang和gcc处理的方言启用了最大优化可能对于一些不涉及处理来自未知来源的输入的特殊目的而言非常好,但是真的不适合大多数人.而不是向后弯腰以在不合适的方言中编写代码,在适当时使用"流行扩展" - 只记录您正在这样做的文档. (2认同)