关于__STDCPP_DEFAULT_NEW_ALIGNMENT__对齐属性、C++17标准要求及new分配内存对齐安全性的技术咨询
关于__STDCPP_DEFAULT_NEW_ALIGNMENT__对齐属性、C++17标准要求及new分配内存对齐安全性的技术咨询
嘿,这个问题抓得特别准,刚好说到了C++内存对齐里容易被忽略但又关键的细节,我来给你拆解清楚:
一、C++17标准对__STDCPP_DEFAULT_NEW_ALIGNMENT__与std::max_align_t的强制要求
首先明确:C++17标准是强制要求__STDCPP_DEFAULT_NEW_ALIGNMENT__ >= alignof(std::max_align_t)成立的,所以你写的那个static_assert在任何合规的C++17编译器下都会通过,不会触发断言失败。
这里的逻辑是:
std::max_align_t是C++标准定义的类型,它的对齐值等于所有标量类型中最大的对齐要求——简单说,只要内存对齐到这个类型的边界,就能容纳任何标量类型的对象。__STDCPP_DEFAULT_NEW_ALIGNMENT__是标准规定的预定义宏,它的数值就是默认new操作符分配内存时的最小对齐要求。标准明确要求这个宏的值不能小于alignof(std::max_align_t),确保默认new出来的内存能满足所有常规标量类型的对齐需求。
二、new std::byte[size]分配的内存对齐安全性
你完全可以放心:默认new分配的std::byte数组,返回的地址一定能安全对齐任何标量类型。
别被std::byte本身的对齐值(是1,因为它是单字节类型)误导——C++17里,默认的数组new操作符的对齐保证不依赖于你要分配的元素类型,不管你new的是std::byte[]、int[]还是其他普通类型数组,它都会返回满足std::max_align_t对齐要求的内存块。而所有标量类型的对齐要求都不会超过std::max_align_t的对齐值,所以你把这块内存转成任何标量类型的指针来使用,都不会出现对齐违规的问题。
补充一句:如果是处理比std::max_align_t对齐要求更高的自定义类型(比如用alignas(64)修饰的类型),那才需要用带对齐参数的重载new,但这和你问的标量类型场景无关。
内容来源于stack exchange
相关产品推荐
相关产品推荐

