使用指针转换来存储/转换值:我打破了严格的别名规则吗
Using pointer conversions to store/cast values: Am I breaking the strict aliasing rule?
这个问题与这篇文章有关。
一些权威用户表示,以下代码违反了严格的别名规则。
#include <boost/static_assert.hpp>
template <typename T>
struct MyType {
private:
T data;
public:
template <typename U>
operator U () {
BOOST_STATIC_ASSERT_MSG(sizeof(U) == sizeof(T),"Trying to convert to data type of different size");
return *((U*) &data);
}
template <typename U>
NeonVectorType<T>& operator =(const U& in) {
BOOST_STATIC_ASSERT_MSG(sizeof(U) == sizeof(T),"Trying to copy from data type of different size");
data = *((T*) &in);
return *this;
}
}
然而,我从来没有使用写入数据的指针,也从来没有共享指向它的指针,所以如果编译器没有意识到这一点,我就看不到变量中包含的值是如何变化的。我的印象是,也许我违反了一些规则,但不是严格的混叠规则。。。
注意:我不知道这有多重要,但我的编译器(gcc 4.9)不会发出警告。
*((U*) &data)
如果是reinterpret_cast
并且类型U
不允许对类型T
进行别名,则会违反严格别名。允许的类型显示在此列表中。
这条规则涉及阅读和写作。
这是一篇很好的文章,解释了规则背后的一些基本原理。
正如在主要的严格混叠线程中所指出的,您可以使用memcpy
作为解决方案,例如:
U u;
memcpy( &u, &data, sizeof u );
return u;
在另一个功能中
memcpy( &data, &in, sizeof data );
请注意,类类型的原始字节副本受到一些限制(我认为类必须是POD,您最好确保它们具有相同的布局)。
然而,我从来没有使用写入数据的指针〔…〕
标准中的语言比这更通用[basic.life]/7有:
[…]一个指针指向原始对象、引用原始对象的引用或原始对象的名称对象[…]
在operator=
中,您使用类型为T
的左值写入data
,在operator U
中,使用类型为U
的指针读取它;其中CCD_ 11和CCD_。
只需使用memcpy
。它保证能工作,而且效率很高(试试)!
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 强制转换为不相关的引用类型是否违反严格的别名规则?
- 包含可变参数包的第一个可转换类型的别名的结构
- 将空基类优化对象强制转换为另一种类型是否会破坏严格的别名?
- 将围绕sockaddr_storage和sockadd_in进行强制转换以打破严格的别名
- 将这些模板转换为别名声明
- 从char数组中强制转换*时,严格的别名规则是什么
- 使用指针转换来存储/转换值:我打破了严格的别名规则吗
- 从成员函数指针到另一个类型的强制转换,返回严格的别名问题
- 通过C强制转换访问结构的第一个字段是否违反了严格的别名
- 将char[]强制转换为usingned int给出:取消引用类型的punned指针将打破严格的别名规则
- c++ 11中的const类型转换为const别名
- 如何防止模板化别名的隐式值保留转换
- 将别名模板强制转换为别名类型
- c++动态向下转换为类模板,其中模板模板参数为类模板或别名模板