Dip*_*ipu 4 c++ casting type-conversion type-punning
打字
指针别名的一种形式,其中两个指针指向内存中的相同位置,但将该位置表示为不同类型.编译器会将"双关语"视为不相关的指针.类型惩罚有可能导致通过两个指针访问的任何数据的依赖性问题.
文章试图说什么?
sup*_*cat 11
类型双关和别名是不同但相关的概念,一些编译器编写者似乎无法区分它们,尽管它们在很大程度上是正交的。
类型双关是指将存储写入为一种类型并读取为另一种类型的情况,通常是为了允许将值解释为位序列,允许将位序列解释为值,或者允许用作其表示匹配的另一种类型的值,至少在感兴趣的部分中。例如,后一种形式的类型双关可能在以下情况下很有用:可能具有指向多种结构类型的指针,所有这些结构类型都共享公共初始序列,并且可能需要对所有结构类型的公共初始序列成员进行操作。尽管结构的类型不同,但这些结构。请注意,尽管标准包含显式保证,这表明后一种形式的类型双关应该是有用的,但将其与别名混淆的编译器不支持此类构造。
别名是指一种不同的概念,其中使用两个或多个同时活动但看似不相关的方式以彼此交互的方式访问存储。给出类似的东西:
int test1(int *p1, int *p2)
{
*p1 = 1;
*p2 = 2;
return *p1;
}
Run Code Online (Sandbox Code Playgroud)
if p1==p2、 thenp1和p2will 别名sincep1将用于访问由p2创建和最后使用之间的某个时间标识的存储p2,在上下文中p1不能从p2[可能是在调用该函数之前p1创建的,但是p2没有办法可以从函数内部p1派生]。p2然而,由于标准允许标识相同类型的左值之间存在别名,因此上述构造将在 时定义行为p1==p2,尽管事实是p1和p2别名。
另一方面,考虑到类似的情况:
struct s1 {int x; };
struct s2 {int x; };
union s1s2 {struct s1 v1; struct s2 v2; } uarr[100];
int test1(int i, int j)
{
int temp;
{ struct s1 *p1 = &uarr[i].v1; temp = p1->x; }
if (temp)
{ struct s2 *p2 = &uarr[j].v2; p2->x = 1; }
{ struct s1 *p3 = &uarr[i].v1; temp = p3->x; }
return temp;
}
Run Code Online (Sandbox Code Playgroud)
这里,指针p1、p2、 和p3具有明显不相交的生命周期,因此不会同时活动并且彼此别名。每个指针都是独立派生自uarr,并且每个指针的生命周期将在下一次使用 之前结束uarr。因此,此代码利用类型双关来访问与 astruct s1和 a相同的存储struct s2,但正如所写的那样,不会利用别名,因为对所讨论的存储的所有访问显然都是从同一个根级对象派生的uarr。
不幸的是,尽管基于类型的访问规则旨在(根据基本原理和脚注)指示何时允许使用别名,但某些编译器以使得诸如公共初始序列保证之类的语言功能本质上无用的方式解释它们,因为他们使用类型访问规则作为借口来重写代码,以删除p3from的派生uarr,从而在没有别名的地方引入别名。
正如它所说,类型双关语就是当你有两个不同类型的指针时,它们都指向同一个位置.例:
// BAD CODE
uint32_t data;
uint32_t* u32 = &data;
uint16_t* u16 = (uint16_t*)&data; // undefined behavior
Run Code Online (Sandbox Code Playgroud)
此代码在C++(和C)中调用未定义的行为,因为不允许通过不兼容类型的指针访问相同的内存位置(有一些特殊的例外).这被非正式地称为"严格别名违规",因为它违反了严格的别名规则.
进行打字的另一种方式是通过工会:
// BAD C++ CODE
typedef union
{
uint32_t u32;
uint16_t u16 [2];
} my_type;
my_type mt;
mt.u32 = 1;
std::cout << mt.u16[0]; // access union data through another member, undefined behavior
Run Code Online (Sandbox Code Playgroud)
这也是C++中未定义的行为(但在C中允许完全正常).
| 归档时间: |
|
| 查看次数: |
1059 次 |
| 最近记录: |