Pio*_*ycz 23 c++ g++ powerpc memory-alignment placement-new
我读过这个 什么时候应该担心对齐?但我仍然不知道我是否要担心放置新运算符返回的对齐指针 - 就像在这个例子中:
class A {
public:
long double a;
long long b;
A() : a(1.3), b(1234) {}
};
char buffer[64];
int main() {
// (buffer + 1) used intentionally to have wrong alignment
A* a = new (buffer + 1) A();
a->~A();
}
Run Code Online (Sandbox Code Playgroud)
__alignof(A) == 4,(buffer + 1)是不对齐的4.但一切正常 - 这里有完整的例子:http://ideone.com/jBrk8
如果这取决于架构,那么我正在使用:linux/powerpc/g ++ 4.xx
[更新]发布此问题后,我读了这篇文章:http://virtrev.blogspot.de/2010/09/memory-alignment-theory-and-c-examples.html.也许在我的情况下唯一的缺点是性能损失,我的意思是未对齐的访问成本超过对齐?
eca*_*mur 19
当您在缓冲区上调用placement new时:
A *a = new (buf) A;
Run Code Online (Sandbox Code Playgroud)
您正在调用内置void* operator new (std::size_t size, void* ptr) noexcept定义:
18.6.1.3安置表格[new.delete.placement]
这些函数是保留的,C++程序可能不会定义用于替换标准C++库(17.6.4)中的版本的函数.(3.7.4)的规定不适用于运营商新的和运营商删除的这些保留的安置形式.
void* operator new(std::size_t size, void* ptr) noexcept;
返回:ptr.
备注:故意不执行任何其他操作.
(3.7.4)的规定包括返回的指针应该适当对齐,所以void* operator new (std::size_t size, void* ptr) noexcept如果传入一个非符号指针,则可以返回.这不会让你摆脱困境,但是:
5.3.4新[expr.new]
[14]注意:当分配函数返回null以外的值时,它必须是指向已保留对象空间的存储块的指针.假设存储块被适当地对准并且具有所请求的大小.
因此,如果将未对齐的存储传递给放置新表达式,则违反了存储已对齐的假设,结果为UB.
实际上,在上面的程序中,如果你替换long long b为__m128 b(之后#include <xmmintrin.h>),那么程序会像预期的那样发生段错误.
Nic*_*las 10
仅仅因为一切似乎都有效并不意味着它确实存在.
C++是一个定义工作所需内容的规范.编译器也可以使不需要的东西工作.这就是"未定义的行为"的含义:任何事情都可能发生,因此您的代码不再可移植.
C++ 不需要这个工作.因此,如果你将代码带到一个不起作用的编译器,你就不能再责怪C++了; 滥用语言是你的错.
| 归档时间: |
|
| 查看次数: |
5129 次 |
| 最近记录: |