强制转换为不相关的引用类型是否违反严格的别名规则? [英] Does casting to an unrelated reference type violate the strict aliasing rule?

查看:145
本文介绍了强制转换为不相关的引用类型是否违反严格的别名规则?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

严格的别名规则说

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

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

-对象的动态类型,

-对象的动态类型的cv限定版本,

— a cv-qualified version of the dynamic type of the object,

-与对象的动态类型相似的类型(定义见4.4)

— a type similar (as defined in 4.4) to the dynamic type of the object,

-一种类型,是与对象的动态类型相对应的有符号或无符号类型

— a type that is the signed or unsigned type corresponding to the dynamic type of the object,

-一种类型,是与对象的动态类型的cv限定版本相对应的有符号或无符号类型

— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,

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

— an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including, recursively, an element or non-static data member of a subaggregate or contained union)

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

I am wondering if the following program already contains undefined behavior and if there is "an access to the stored value":

#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);
    }

从我所见,将float指针转换为int引用等效于`* reinterpret_cast(& x):

From what I see, the cast of the float pointer to the int reference is equivalent to `*reinterpret_cast(&x):

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

A glvalue expression of type T1 can be cast to the type "reference to T2" if an expression of type "pointer to T1" can be explicitly converted to the type "pointer to T2" using a reinterpret_cast The result refers to the same object as the source glvalue, but with the specified type. [ Note: That is, for lvalues, a reference cast reinterpret_cast(x) has the same effect as the conversion *reinterpret_cast(&x) with the built-in & and * operators (and similarly for reinterpret_cast(x)). —end note ]

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

For pointers, reinterpret_cast boils down to conversion to void* and then to the target type:

可以将对象指针显式转换为其他类型的对象指针.72当对象指针类型的prvalue v为 转换为对象指针类型"pointer to cv T",结果是 static_cast(static_cast(v)).

An object pointer can be explicitly converted to an object pointer of a different type.72 When a prvalue v of object pointer type is converted to the object pointer type "pointer to cv T", the result is static_cast(static_cast(v)).

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

The semantics of the two static casts are defined as:

指针指向cv1无效"类型的prvalue可以转换为指针指向cv2 T的类型"的prvalue,其中T是对象类型,而cv2 与以下职位具有相同的简历资格,或具有更高的简历资格, cv1.空指针值将转换为的空指针值 目标类型.如果原始指针值代表 内存中一个字节的地址A且满足对齐要求 T的要求,则结果指针值表示相同 地址作为原始指针值(即A). 其他未指定此类指针转换.

A prvalue of type "pointer to cv1 void" can be converted to a prvalue of type "pointer to cv2 T," where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. The null pointer value is converted to the null pointer value of the destination type. If the original pointer value represents the address A of a byte in memory and A satisfies the alignment requirement of T, then the resulting pointer value represents the same address as the original pointer value, that is, A. The result of any other such pointer conversion is unspecified.

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

Since int32_t and float have same size and alignment, I should get a new pointer pointing to the same address. What I am wondering is if

参考演员表reinterpret_cast(x)与 使用内置的&转换* reinterpret_cast(& x)和*运算符

a reference cast reinterpret_cast(x) has the same effect as the conversion *reinterpret_cast(&x) with the built-in & and * operators

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

already constitutes an access to the stored value or if that must be made somewhere later to violate the strict aliasing rule.

推荐答案

您进行的强制转换无法访问对象if.

The casts you made are not an access to the objects i or f.

3.1访问 [defns.access]

执行时间操作"以读取或修改对象的值

⟨execution-time action⟩ to read or modify the value of an object

由于您的程序未尝试执行上述操作,因此它没有违反严格的别名.但是,尝试使用这些指针/引用进行读取或写入将是违反的.因此,这是一条很好的路线.但是,仅获得引用/指针并不违反您所述的第一段.强制转换为不相关的引用/指针类型仅处理对象的身份/地址,而不涉及对象的值.

Since your program does not attempt to do the above, it does not violate strict aliasing. Trying to use those pointers/references to read or write will be a violation, however. So this is a fine line to tread. But merely obtaining the references/pointers is not against the first paragraph you stated. Casting to unrelated reference/pointer types only deals with an object's identity/address, and not its value.

这篇关于强制转换为不相关的引用类型是否违反严格的别名规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆