如何解决std :: swap丢失基于类型的别名分析所使用的信息吗?
通过检查GCC标头(vector
中stl_vector.h
类的实现,我在向量基本实现类内找到了以下两个成员函数(在示例中,我将其重命名为{{ 1}},以避免使用long_and_weird名称。
Data_Class
成员( void
_M_copy_data(Data_Class const& __x) _GLIBCXX_NOEXCEPT
{
_M_start = __x._M_start;
_M_finish = __x._M_finish;
_M_end_of_storage = __x._M_end_of_storage;
}
void
_M_swap_data(Data_Class& __x) _GLIBCXX_NOEXCEPT
{
// Do not use std::swap(_M_start,__x._M_start),etc as it loses
// information used by TBAA.
Data_Class __tmp;
__tmp._M_copy_data(*this);
_M_copy_data(__x);
__x._M_copy_data(__tmp);
}
,_M_start
,_M_finish
)只是某种类型的指针,并且是类中的唯一成员。
这里的问题是第二个函数中进行注释的原因是什么?
可能出于相同的原因,但是为什么不对两个_M_end_of_storage
对象使用std::swap
,或者至少不使用自动生成的Data_Class
进行复制呢?
我觉得这可以简化。
解决方法
对于std::vector
对象,三个包含的指针将永远不会与另一个std::vector
中的指针寻址相同的内存-每个指针都管理自己的连续内存区域。这种见解可用于基于类型的别名优化,如果各个指针以编译器能够遵循和推理的方式来回移动,则这种可能性将继续存在。
std::swap
可以使用一些就地位欺骗手段来实现,以使编译器无法执行该跟踪(请参见here),因此最好避免。
当然,没有任何内在因素阻止优化器跟踪swap
所做的事情并将其识别为与使用__tmp
的代码相同的逻辑操作,但是无论发表评论的人和选择不使用std::swap
可能会观察到或推断出,对于某些优化级别,至少在 他们使用的编译器的一个版本上也未对其进行优化。最糟糕的优化可能很普遍。
相同类型的观察/推理可能导致他们避免使用默认的operator=
。例如,假设其编译器上的实现可能类似于memcpy
-如果您将数据视为具有char
类型,则可以避免别名错误(以同样的方式,您只能安全地对序列进行排序)对不同的union
成员的访问权限是char
或char[]
),但这是因为抑制了混叠优化。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。