Bjö*_*lex 2 c++ struct pointers strict-aliasing c++11
考虑以下程序:
#include <algorithm>
#include <iostream>
#include <vector>
struct foo {
foo(int value)
: value_(value)
{
// perform range checks
}
int value() const {
return value_;
}
private:
int value_;
};
int main() {
std::vector<foo> values{0, 1, 2, 3, 4, 5};
std::for_each(std::begin(values), std::end(values),
[](foo& f){ std::cout << f.value(); });
std::cout << std::endl;
std::for_each(reinterpret_cast<const int*>(values.data()),
reinterpret_cast<const int*>(values.data()) + values.size(),
[](int i){ std::cout << i; });
}
Run Code Online (Sandbox Code Playgroud)
用Apple LLVM 6.0版(clang-600.0.54)(基于LLVM 3.5svn)编译后,它产生以下输出(这正是我想要的):
012345
012345
Run Code Online (Sandbox Code Playgroud)
第一次迭代是微不足道的.然而,第二次迭代不是通过迭代器执行,而是通过指向已转换为底层存储的指针const int*执行.
我的问题是:该代码合法吗?
我的直觉是它.根据C++ 11标准的§5.2.10/ 7(最终工作草案):
当类型的prvalue V"指针
T1"被转换为类型"指针CVT2",结果是static_cast<cvT2*>(static_cast<cvvoid*>(v))如果两个T1和T2是标准布局类型(3.9)和的对准要求T2并不比那些更严格T1
如果我正确解释,那么上面的代码应该是正确的,对吗?如果没有,它可以成功吗?
(在我的回答中,我使用C++ 14标准草案(N4140),这与C++ 11在相关引用方面略有不同)
reinterpret_cast<const int*>(values.data())很好,因为[class.mem]/19:
如果标准布局类对象具有任何非静态数据成员,则其地址与其第一个非静态数据成员的地址相同.(...)[注意:因此,在标准布局结构对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐. - 尾注]
关于解除引用,[expr.reinterpret.cast]/7:
可以将对象指针显式转换为不同类型的对象指针.当对象指针类型的prvalue v被转换为对象指针类型"指向cv的指针
T"时,结果是static_cast<cv T*>(static_cast<cv void*>(v)).
首先static_cast是[conv.ptr]/2:
类型为"指向cv的指针"的prvalue
T,其中T是对象类型,可以转换为类型为"指向cv的指针"的prvaluevoid.将指针的非空指针值转换为对象类型的结果为"指向cv的指针void"表示存储器中与原始指针值相同的字节的地址.
第二static_cast- [expr.static.cast]/13:
类型为"指向cv1 void的指针"的prvalue可以转换为类型为"指向cv2 T的指针"的prvalue(...)如果原始指针值表示内存中字节的地址A并且A满足对齐要求然后,结果指针值表示与原始指针值相同的地址,即A.
因为对齐要求得到满足[class.mem]/19,所以演员工作正常.
但问题是sizeof(foo) == sizeof(int)除了上述要求之外似乎无法保证std::complex.人们可以将关于未命名填充的注释解释[class.mem]/19为仅在需要对齐时允许填充,因此在您的情况下不得有任何填充,但在我看来,这方面的注释太模糊了.
您可以做的是放入您的代码
static_assert(sizeof(foo) == sizeof(int), "");
// this may be paranoic but won't hurt
static_assert(alignof(foo) == alignof(int), "");
Run Code Online (Sandbox Code Playgroud)
因此,如果违反要求,至少您的代码将无法编译.
| 归档时间: |
|
| 查看次数: |
453 次 |
| 最近记录: |