在满足对齐要求的数组缓冲区奇数偏移写入数据是否会引发未定义行为?
问题分析:对齐违规与未定义行为
示例代码
int main(){ alignas(double) unsigned char buff[10] = {0}; char* ptr = buff; ptr++; *(double*)ptr = 1.0; // #1 double r = *(double*)ptr; //#2 }
引用标准条款
对象类型具有对齐要求(见[basic.fundamental]、[basic.compound]),这些要求对可分配该类型对象的地址施加限制。
尝试在不满足对象类型对齐要求的存储空间中创建对象(见[intro.object])属于未定义行为(UB)。
代码逐点分析
偏移后的地址是否满足double的对齐要求?
- 缓冲区
buff通过alignas(double)确保起始地址符合double类型的对齐要求。 ptr++后,指针指向的地址相对于起始位置偏移了sizeof(char)(C++标准规定sizeof(char)恒为1)。- 在所有合规平台上,
double的对齐要求至少为2字节(主流架构如x86_64、ARM64中为8字节),偏移1字节后的地址对齐模数为1,完全不满足double的对齐要求。
#1和#2的操作是否引发未定义行为?
- #1处的写入操作:
*(double*)ptr = 1.0本质是在未满足对齐要求的地址上创建double对象并赋值,完全命中标准条款中“在不满足对齐要求的存储空间中创建对象”的情况,属于未定义行为。 - #2处的读取操作:由于#1已经因对齐违规触发了未定义行为,后续对该对象的读取操作是UB的延续,同样属于未定义行为。
内容的提问来源于stack exchange,提问作者xmh0511
相关产品推荐
相关产品推荐

