我目前尝试用 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; ... }
我如何确保我的 x
、y
、width
和 height
始终位于正确的位置内存明智?
在一开始就“只是”将它们按相同的顺序排列就足够了吗?
另外,如何设计方法头来接受它?
最佳答案
如果所有结构都以相同类型的成员开始,以相同的顺序,相应的成员将具有相同的偏移量。大多数编译器都可以配置为允许使用任何结构类型的指针来检查任何其他公共(public)初始序列的成员,但存在一些问题:
在一些不常见的平台上,如果对象后跟填充字节,则将对象和填充字节一起写入的指令(可能在后者中存储无意义的值)可能比仅写入对象的指令更快。如果某个成员在某些结构中后跟一个填充字节,但在另一个结构中跟一个有意义的数据,则使用后跟填充字节的类型对该成员进行写入可能会用无意义的值覆盖“填充字节”,从而破坏这些值其他结构类型中的以下成员。我不知道当前使用的任何体系结构对于除位域以外的任何结构成员来说都是一个问题,而且我不知道任何当前的实现即使对于那些也是一个问题,但这种可能性可能会出现在某些平台上,尤其是位域。
给定如下内容:
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/