强制转换为不相关的引用类型是否违反严格的别名规则?



严格的混叠规则说

如果程序尝试通过以下方式访问对象的存储值 不是以下类型之一的 glvalue 行为是 定义:

— 对象的动态类型,

— 对象的动态类型的 CV 合格版本,

— 与对象的动态类型类似的类型(如 4.4 中所定义(,

— 与对象的动态类型对应的有符号或无符号类型,

— 一种类型,它是有符号或无符号的类型,对应于对象的动态类型的 CV 限定版本,

— 在其元素或非静态数据成员中包含上述类型之一的聚合或联合类型(递归地包括子聚合或包含的联合的元素或非静态数据成员(

我想知道以下程序是否已经包含未定义的行为,以及是否有"对存储值的访问":

#include <cstdint>
void foo() {
std::int32_t i = 1;
float f = 1.0f;
std::int32_t& r = reinterpret_cast<std::int32_t&>(f);
std::int32_t* p = reinterpret_cast<std::int32_t*>(&f);
}

据我所知,浮点指针对 int 引用的强制转换等效于 '*reinterpret_cast(&x(:

如果可以显式使用"指向 T1 的指针"类型的表达式,则可以将类型为 T1 的 glvalue 表达式转换为类型"对 T2 的引用" 转换为类型"指向 T2 的指针",使用 reinterpret_cast 结果引用与源 glvalue 相同的对象,但具有 指定的类型。[ 注意:也就是说,对于左值,引用强制转换 reinterpret_cast(x( 与转换具有相同的效果 *reinterpret_cast(&x(与内置的&和*运算符(reinterpret_cast(x(类似(。—尾注 ]

对于指针,reinterpret_cast归结为转换为 void*,然后转换为目标类型:

对象指针可以显式转换为不同类型的对象指针。72 当对象指针类型的 prvalue v 为 转换为对象指针类型"指向 cv T 的指针",结果为 static_cast(static_cast(五((。

两个静态强制转换的语义定义为:

类型为"指向 cv1 void 的指针"的 prvalue 可以转换为"指向 cv2 T 的指针"类型的 prvalue,其中 T 是对象类型,cv2 与简历资格相同,或高于 简历1.空指针值将转换为空指针值 目标类型。如果原始指针值表示 内存中一个字节的地址 A 和 A 满足对齐方式 要求 T,则生成的指针值表示相同 地址作为原始指针值,即 A。任何结果 其他此类指针转换未指定。

由于int32_tfloat具有相同的大小和对齐方式,因此我应该得到一个指向相同地址的新指针。我想知道的是,如果

引用强制转换 reinterpret_cast(x( 具有与 转换 *reinterpret_cast(&x( 与内置的 & 和 * 运算符

已经构成对存储值的访问,或者如果以后必须在某个地方进行访问以违反严格的别名规则。

您所做的转换不是对对象if的访问。

3.1 访问[defns.access]

⟨执行时操作⟩读取或修改对象的值

由于您的程序不会尝试执行上述操作,因此它不会违反严格的别名。但是,尝试使用这些指针/引用进行读取或写入将是一种违规行为。所以这是一条细线。但是,仅仅获得参考/指针并不反对您所说的第一段。强制转换为不相关的引用/指针类型仅处理对象的标识/地址,而不处理其值。

最新更新