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

标签 c struct generic-programming

我目前尝试用 C 编写一些简单的文字控制台游戏来获得乐趣。

为此,我需要能够在……嗯……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; ... }

我如何确保我的 xywidthheight 始终位于正确的位置内存明智? 在一开始就“只是”将它们按相同的顺序排列就足够了吗?

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

最佳答案

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

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

  2. 给定如下内容:

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

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

使用通用初始序列规则的代码几乎可以在任何适当配置的编译器上可靠地工作,但是像 gcc 和 clang 之类的代码必须使用 -fno-strict-aliasing 特别配置> 选项。自 1974 年以来,利用公共(public)初始序列保证的能力一直是该语言的一个公认部分,并且在编写标准时,任何熟悉该语言的人都会理解它被设计为允许像上面那样的构造,编译器应该不难识别。由于该标准的作者未能明确要求以有用的方式兑现 CIS 保证,因此 clang 和 gcc 的作者决定他们宁愿声称依赖于已有数十年历史的 CIS 保证的程序“已损坏”尊重 40 多年的先例。

关于c - 多个结构,需要在方法中访问的相同字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52749409/

上一篇:c - float 不添加?

下一篇:c - 打印负数

相关文章:

c - 是否有正则表达式可以修剪小数点后两位数字?

在链接时定义的 C 常量

c - 将指针传递给 c 中的 strcpy 函数

c - 我应该在套接字生命周期内什么时候设置 TCP_QUICKACK 选项?

python - 在 Cython 中创建 C 结构

c++ - C++中的 union (请解释一下)

c++ - 使用 UML 表示在 C++ 模板类中定义的 typedef

c - ergo wergo weigo

c++ - 使用任意类型的给定参数进行任意操作的任何建议?

c++ - 类似于 C++ 中 Perl 的 AUTOLOAD 的功能