[英]std::swap loses information used by Type-Based Alias Analysis?
By examining the implementation of the vector
class in the GCC headers ( stl_vector.h
), I found the following two member functions inside the vector base implementation class (Which I renamed in the example as Data_Class
to avoid long_and_weird name).通过检查 GCC 头文件 (
stl_vector.h
) 中vector
类的实现,我在向量基实现类中发现了以下两个成员函数(我在示例Data_Class
其重命名为Data_Class
以避免使用 long_and_weird 名称)。
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);
}
The members ( _M_start
, _M_finish
, _M_end_of_storage
) are just pointers of some type and are the only members in the class.成员(
_M_start
、 _M_finish
、 _M_end_of_storage
)只是某种类型的指针,并且是类中唯一的成员。
The question here is what is the reason for the comment in the second function?这里的问题是第二个函数中注释的原因是什么? It may be for the same reason, but why not use
std::swap
for two Data_Class
objects or maybe at least an automatically generated operator=
to do the copying?可能出于同样的原因,但为什么不对两个
Data_Class
对象使用std::swap
或者至少使用一个自动生成的operator=
来进行复制?
I feel like this could be done simpler.我觉得这可以做得更简单。
For a std::vector
object, the three contained pointers will never address the same memory as the pointers in another std::vector
- each manages its own contiguous memory region.对于
std::vector
对象,三个包含的指针永远不会与另一个std::vector
的指针寻址相同的内存——每个指针都管理自己的连续内存区域。 This insight can be used for type-based aliasing optimisations, which continue to be possible if the individual pointers are moved around in a way the compiler's able to follow and reason about.这种洞察力可用于基于类型的别名优化,如果单个指针以编译器能够遵循和推理的方式移动,这将继续成为可能。
std::swap
may be implemented using some in-place bitwise trickery such that the compiler can't perform that tracking (see here ), so is best avoided. std::swap
可以使用一些就地按位技巧来实现,这样编译器就无法执行该跟踪(请参阅此处),因此最好避免。
Of course, there's nothing inherently preventing an optimiser from being able to track whatever swap
does and recognising it as the same logical operation as the __tmp
-using code, but whomever made that comment and the choice not to use std::swap
probably observed or deduced that it wasn't optimised as well on at least one version of the compiler they used, for some optimisation level.当然,没有什么本质上阻止优化器能够跟踪
swap
所做的任何事情并将其识别为与__tmp
使用代码相同的逻辑操作,但是__tmp
谁提出该评论并选择不使用std::swap
可能观察到或推断它没有在他们使用的至少一个版本的编译器上针对某些优化级别进行优化。 Worse optimisation could be quite common though.不过,更糟糕的优化可能很常见。
The same type of observation/reasoning may have led them to avoid a default operator=
.相同类型的观察/推理可能导致他们避免使用默认的
operator=
。 For example, say the implementation on their compiler may have been akin to a memcpy
- if you treat the data as having char
type then you're safe against aliasing bugs (same way you can only safely sequence access to distinct union
members is one is a char
or char[]
), but that's because aliasing optimisations are suppressed.例如,假设他们的编译器上的实现可能类似于
memcpy
- 如果您将数据视为具有char
类型,那么您就可以安全地避免别名错误(同样,您只能安全地对不同union
成员的访问进行排序是一个char
或char[]
),但这是因为别名优化被抑制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.