【发布时间】:2016-04-19 00:04:32
【问题描述】:
最近我在阅读有关小字符串优化 (SSO) 的文章:What are the mechanics of short string optimization in libc++?。众所周知,一个字符串通常由 3 个指针组成,在 64 位系统上为 24 个字节。链接的答案说,在 libc++ 的实现中,第一个指针的第一位用于指示字符串是处于“长”还是“短”模式,即堆分配和外部存储与最多 22 个字符的内部存储.
然而,这假设第一个指针的第一位永远不可能有意义地成为地址的一部分,因为每当字符串处于“长”模式时,该位将始终设置(或取消设置,具体取决于选择的约定) )。从表面上看,这似乎是合理的,因为 64 位指针允许 2^64 个地址,大于 1 后跟 18 个字节的零,或超过 10 亿 GB。
所以这是合理的,尽管不确定。我的问题是:这在某处有保证吗?如果有保证,在哪里保证?通过架构规范,还是通过其他方式?更进一步:使用多少位是安全的?我有一个模糊的回忆,在某处只使用了 48 位,但我不记得了。
如果有一些位数,例如8 或 16 保证不会受到影响,这肯定是可以通过一些有趣的方式加以利用的东西。利用这一点会很好,但不会以在某些机器上出现代码神秘故障为代价。
【问题讨论】:
-
Itanium 和 Alpha 是非常不同的平台。您能做的最好的事情就是说明操作系统使用的内存布局。
-
@ Flexo 好吧,这已经是部分答案了,如果安腾规范对此有话要说,那么这就是一个开始。
-
已经投票关闭?我能问为什么吗?
-
它更有可能是最不重要位,而不是最位。长字符串缓冲区将从堆中分配,并且几乎可以肯定是 8 字节对齐(至少),因此底部四位为零。这样可以避免对整体内存布局做出任何假设。
-
您在多个方面都犯了错误。短字符串标志根本不与指针重叠,它与保存长字符串的 size 的字段重叠。即使它确实与指针重叠,它也会是指针的低位,这意味着内存 range 不会进入它,只是对齐。