@
pastor 你往上翻一下#88 ,我在那里解释了为什么我管它叫 list_head (以及最大的问题并不是它叫什么,而是 target 因为 non-owning 的性质不应该用同样的类型)和为什么后来我觉得这个强制转换不是 UB 。
首先最快速验证正确性的话……你可以丢进 compiler explorer 里面看汇编。gcc 整蛊就不说了(在那个时候我这个版本生成更短的汇编,而主楼那个写法不知道为什么看起来循环被手动展开了一层),在 msvc 和 clang 下面都会生成跟主楼的写法一模一样的汇编。当然,编译语言不是实验科学,生成汇编一样也不一定语义上正确,所以还需要再解释一下这里在干什么:你不要想着谁是几级指针这种事,这里做的是把指向一个 struct 第一个元素的指针转化成了指向这个 struct 本身的指针,这个是 C/C++标准明确允许的指针转换,所以我才刻意把 next 放在 value 前面,并不是运气好,所有符合标准的编译器都会保证它是对的。在转换后我对那个指针的唯一用法是使用它所指的 struct 的第一个元素,而不是解引用之后对整个 object 做什么,这意味着我始终在用同样的类型访问同样的一块内存,不会产生 strict aliasing 的问题。
你后面打算把它写成 auto p = head;肯定是不对的,p 大概代表比原来链表的头更前的一个节点,你这么写是删不掉第一个节点的。你可以再跟#25 那个版本比较一下,主体是差不多的,我只不过是没有给那边的「头节点」分配不必要的内存而已。