微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

这种C标准的标记方法是否符合标准?

(对于指针标记的重述:其中对象的大小意味着其指针中的有限位数将始终未使用,并且可以重新用于其他用途,例如标记对象的类型.)

excellent answer到我的previous question在这个问题上证实,将指针转换为整数和对整数进行处理的天真的方法在技术上不能依赖于工作(不考虑其在实践中的流行度).

再考虑一下,我想我有一个解决方案适用于原始问题中描述的具体情况(所有对象的大小相同,所有对象都从单个“堆”数组分配).有人可以确认我的推理吗

// given:
typedef Cell ...; // such that sizeof(Cell) == 8
Cell heap[1024];  // or dynamic,w/e

// then:
void * tagged = ((char *)&heap[42]) + 3;  // pointer with tag 3 (w/e that means)

int tag = ((char *)tagged - (char *)heap) % sizeof(Cell);  // 3
Cell * ptr = (Cell *)((char *)tagged - tag);               // &heap[42]

换句话说:没有关于指针的整数表示的假设.通过索引指向对象中的字节来应用标记. (这肯定是允许的.)

指针减法返回相同数组中两个对象的索引的差异.对象内的字节地址应该是连续的,因此通过获取寻址字节的索引并从该索引中删除所有以前的所有单元格的大小,将标记的值转换为标签;标记的指针可以通过删除现在已知的索引偏移量来还原到单元格指针.

这是否符合标准,因此是一种便携式的指针标记方法?如果在这种情况下将数组的类型转换为其他字符,则指针减法是否仍然可以工作?我可以这样使用sizeof(Cell)吗?

(不,我不知道为什么这个技术性在我心中好多了,是的,可移植性很容易通过其他方式实现.)

解决方法

在这里,我认为唯一需要更加谨慎的是整数类型.不要使用int:

>指针差异的正确类型是ptrdiff_t.
> sizeof的结果是size_t为无符号类型
>你在size_t类型和ptrdiff_t之间做%,所以结果最可能是size_t,所以是一个无符号的值
>将size_t转换为int是实现定义的(所以不可移植),通常它只会丢弃高位位

int将会工作很长时间,但是在64位处理器上使用非常大的阵列的那一天,你会后悔(经过几天的调试)

原文地址:https://www.jb51.cc/c/112570.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐