能否使用std::bit_cast将std::span<A>转为std::span<B>并合规访问?
结论
这个用法不符合C++标准规范,属于未定义行为,即使在当前版本的三大编译器上运行符合预期,也不代表代码是合法、可靠的。
具体原因
- 首先
std::bit_cast这一步转换本身是合法的:std::span是可平凡复制类型,你已经通过静态断言确保了sizeof(A) == sizeof(B),因此std::span<A>和std::span<B>的大小相等、都满足可平凡复制要求,符合std::bit_cast的基本使用条件。 - 问题出在后续通过
spanOfB访问元素的操作,违反了C的严格别名规则:
C标准明确规定,一个对象只能通过以下几类左值访问其存储:- 对象本身的类型,或其const/volatile修饰版本
- 与对象类型兼容的类型
char、unsigned char、std::byte三类字符类型
你的代码里arrayOfA的元素类型是struct A,而spanOfB的元素类型是完全独立的struct B,二者没有继承关系、也不属于兼容类型,哪怕二者大小、对齐一致,成员布局看起来相似,也不允许用B类型的左值访问A类型的对象,这类操作属于标准明确规定的未定义行为。
- 你现在测试运行正常只是巧合:当前主流编译器没有在这类场景下做激进的别名优化,所以暂时没有出问题,但如果后续编译器版本升级、优化等级调整,或者代码上下文变动触发了别名相关的优化,你的代码完全可能出现不可预期的错误。
内容的提问来源于stack exchange,提问作者Lewis Liman
相关产品推荐
相关产品推荐

