- 主题:reinterpret_cast<uint *>(void *) 碰到未对齐内存会出错吗?
没报错看来是运气好,小白承蒙微软照顾了。
【 在 z16166 的大作中提到: 】
: 手册能查到。x86(包括x64)的对齐检查通过下面三个东西控制是否启用:
: 1、CR0寄存器的AM位(Alignment mask)。ring 0才能修改这个位。要测试必须写个kernel module。
: 2、EFLAGS寄存器的AC位(Alignment check)。ring 3就能修改这个位。
: ...................
--
FROM 123.150.181.*
对齐运算速度是快些,而我以前拿gromacs里一些函数测了测,{copy至对齐+后续运算}耗时比{_mm256_loadu+后续运算}长百分之几~十。所以我习惯不对齐直接拿来算
【 在 Bernstein 的大作中提到: 】
: m128、m256之类的,用simd指令的话,如果不对齐会出问题
: 其他类型x86上应该没问题
:
--
FROM 123.150.181.*
那是肯定的
MS以前有个老帖子,论述比较清楚,而且有性能对比测试的现成代码,MS自家居然给删了
幸好有人mirror了
Windows Data Alignment on IPF, x86, and x86-64
https://blog.csdn.net/zade/article/details/549411
【 在 Akyrum 的大作中提到: 】
: 对齐运算速度是快些,而我以前拿gromacs里一些函数测了测,{copy至对齐+后续运算}耗时比{_mm256_loadu+后续运算}长百分之几~十。所以我习惯不对齐直接拿来算
: :
--
FROM 114.241.227.*
也就是说,从 c/cpp 标准看。。直接
int64 load_int64(void *src) {
return *static_cast<int*>(src);
}
这个函数的行为是未定义的是吗?在不同的机器底下,可能会有不同的结果,或者异常?
【 在 z16166 (Netguy) 的大作中提到: 】
: 单纯的cast肯定不会报错,只是deref时可能触发系统异常。也就是语言或者编译器无要求,只是硬件/os的要求。
: x86是没问题的(只是默认情况下。有寄存器开关的),随便align。
: windows下只有kerner driver或者少数的API对于传入的mem有align要求。API的align要求一般也是下层的kernel driver或者硬件引起的。不过这个传参的align和deref的align有差异。
: ...................
--
FROM 140.224.35.*
咬文嚼字一下。感觉啃pdf有点无聊了
一、
void比较特殊,是个incomplete type,而且不能成为complete type。
incomplete type没有"对齐要求"这一说法,所以printf("%u", alignof(void))这样的编译不过去。
C++ 17的"8.2.10 Reinterpret cast"这一节明确说了,只有满足这一节的第2到第11条的,才能显式使用reinterpret_cast。
不满足这几条的,到底是forbidden,还是unspecified behaviour,还是undefined behaviour,没明说。
由于void没有对齐的说法,所以reinterpret_cast<uint *>(void *)是不满足上述第2到第11条的。
而reinterpret_cast<short *>(int *)这种可以认为满足第7条,是OK的。
二、
static_cast是8.2.9节描述的,这一节的第13条对"void *"转换成"T *"有明确描述,如果不满足T的对齐要求,转换结果是unspecified。
三、
访问指针指向的内存,在"6.10 Lvalues and rvalues"这一节对glvalue的访问有描述。
第8条规定了8种情况,不符合这8种情况的,都属于undefined。
https://github.com/SuperCV/Book/blob/master/CXX/ISOIEC-14882-2017.pdf
【 在 hgoldfish 的大作中提到: 】
: 也就是说,从 c/cpp 标准看。。直接
: int64 load_int64(void *src) {
: return *static_cast<int*>(src);
: ...................
--
修改:z16166 FROM 114.241.227.*
FROM 114.241.227.*