首页 > 解决方案 > c++中指针的类型是如何实现的?

问题描述

指针类型,如int*,char*float*指向不同的类型。但我听说指针只是简单地实现为指向其他地址的链接 - 那么这个链接如何与编译器可以与链接地址的类型(该位置的变量)匹配的类型相关联?

标签: c++

解决方案


类型主要是中的编译时事物。变量的类型在编译时用于确定操作(在其他 C++ 代码中)对该变量执行的操作。

因此,当您bob使用类型变量时,它会在运行时映射到一个通用指针大小的整数,该整数增加.int*++sizeof(int)

在某种程度上,这是一个谎言;C++ 的行为是根据抽象机器而不是具体机器来指定的。编译器将您的代码解释为在该抽象机器(不存在)上表达操作,然后编写在具体硬件上实现这些操作(只要它们被定义)的具体汇编代码。

在那个抽象的机器里,int*不仅仅是数字。如果您取消引用 a并写入某些内存,则对 a 执行相同操作,并且内存重叠,在抽象机器中,结果是未定义的行为。double*int*double*

在该抽象机器的具体实现中,作为数字的指针int*double*使用相同地址取消引用会导致非常明确的行为。

这种差异很重要。编译器可以自由地假设抽象机(其中int*double*是非常不同的事物)是唯一重要的现实。因此,如果您写入 a int*,写入 adouble*然后从int*编译器读回可以跳过回读,因为它可以证明在抽象机器中写入 adouble*不能更改 aint*指向的值。

所以

int buf[10]={0};
int* a = &buff[0];
double* d = reinterpret_cast<double*>(&buff[0]);
*a = 77;
*d = 3.14;
std::cout << *a;

std::cout << *a编译器可以跳过明显的读取。同时,如果它真的发生在真实的硬件上,它会读取*d写入生成的位。

在推理 C++ 时,您必须同时考虑 3 件事;编译时发生了什么,抽象机器行为以及代码的具体实现。其中两个(编译时和抽象机)int*的实现方式与float*. 在实际运行时,int*两者float*都将是寄存器或内存中某处的 64 位或 32 位整数。

类型检查在编译时完成。错误会发生,或者永远不会发生,不包括 RTTI(运行时类型信息)的情况。

RTTI 类似于dynamic_cast,它不适用于指向float*or之类的原语的指针int*

编译时,该变量带有一个事实,它int*无处不在。在抽象机器中,同上。在具体的编译输出中,它忘记了它是一个int*.


推荐阅读