这是我的结构:
struct Node { struct Node* data; struct Node* links[4]; }
假设没有填充, Node->links[-1]
保证指向Node::data
?
不保证; 这是未定义的行为:
在实践中,您很可能最终指向data
,但任何访问它的尝试都将导致UB。
数组下标是根据指针算法定义的,C99标准对指针算法有这样的说法:
如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义。
因此,严格来说,访问Node->links[-1]
(即使只是获取Node->links[-1]
的地址)也是未定义的行为。 所以你不能保证Node->links[-1]
会得到Node::data
。
但正如许多评论家所提到的那样,它几乎总能奏效。 我仍然认为应该避免的编程习惯很差。 如果不是技术性,那么因为它要求对struct Node
修改很容易导致编译器无法帮助你的错误。 当有人在data
和links
之间添加内容时,事情会神秘地破坏。
union
可能会帮助你。 像这样的东西:
struct Node { union { Node *data; struct { Node *lnk[5]; } links; } }
我会说是,但为什么不宣布它为
struct Node { struct Node* links[5]; }
几乎是的
是的,它几乎肯定会指向data
,但它可能不是一个保证。
你确实得到了一个保证, x[-1]
和*(x - 1)
,所以,根据你在x - 1
的地址放置的东西,那么你确实有一种保证。 (并且不要忘记,当从指针中减去时,减量是项目的大小。)
虽然其他人在严格别名的基础上提出异议,但在这种情况下类型是相同的,因此精心优化不应该删除您预期的行为。
我觉得是这样的。 但是标准没有保证没有填充。
编辑:但是标准还说如果“数组下标超出范围,行为是未定义的,即使某个对象显然可以使用给定的下标访问”。
这是实现定义,取决于实现焊盘结构和数组的方式。 但是,只要它以相同的方式填充结构和数组,它应该工作。
以上就是c/c++开发分享C负数组索引相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/560557.html