代码之家  ›  专栏  ›  技术社区  ›  Narek

编译器如何理解指针类型?

  •  3
  • Narek  · 技术社区  · 15 年前

    C++编译器是如何理解指针类型的?我知道指针的大小等于OS的字(32或64)。那么它是否在32(或64)位中存储了一些关于类型的信息?只是因为您不能在一个类型上有一个指针,并且不能将另一个具有不同类型的指针赋给该指针。

    7 回复  |  直到 15 年前
        1
  •  4
  •   AshleysBrain    15 年前

    指针通常只是基于x86架构的内存地址(我不知道其他架构)。编译器在编译时使用不同的指针来强制类型安全,因为将指向char的指针赋给指向int的指针毫无意义,尤其是因为指向的对象大小不同(因此,如果访问它们,您将获取随机内存)。您可以显式地重写它,并使用 reinterpret_cast<T> 或与其他类型的类铸件 static_cast<T> dynamic_cast<T> (后两种通常是由于“更安全”而推荐的,但都有各自的用途)。

    因此,在机器级别,内存地址只是一个内存地址,CPU将尽职尽责地对其进行任何访问或调用。但是,这是危险的,因为您可能会混淆类型,并且可能不知道它。编译时检查有助于避免这种情况,但通常没有关于运行时存储在指针内部的实际类型的任何信息。

    使用迭代器(STL提供的指针包装器)的一个优点是许多实现都有很多额外的检查 可以 在运行时启用:就像检查您是否使用了正确的容器一样,当您比较它们时,它们是相同类型的迭代器,等等。这是在指针上使用迭代器的一个主要原因——但是标准并不要求使用迭代器,所以请检查您的实现。

        2
  •  10
  •   James McNellis    15 年前

    编译器知道指针是什么类型,因为源代码指出指针是什么类型:

    int* ip;   // ip is a pointer to an int
    
    float* fp; // fp is a pointer to a float
    
    void* vp;  // vp is a pointer to some unknown type; need to cast it to a pointer
               // to an actual type in order to access the pointed-at object
    
        3
  •  4
  •   Community CDub    8 年前

    AS James 也就是说,编译器“知道”指针是什么类型的,因为你告诉它。

    不过,在封面下发生的事情(在一个非常简单的解释中)就不那么轻率了,解析器在阅读代码时,会用需要检查的信息注释其中的每一个重要部分,并强制执行它正在识别的语言规则。因此,给出这个示例代码:

    int*    ip;
    // do some stuff
    double* dp = ip;
    

    编译器将在幕后执行类似的操作(同样是非常简单的形式):

    六羟甲基三聚氰胺六甲醚。。。有一种叫做“IP”的东西。我最好记下它是一个整数指针。好的,这是一个叫做“dp”的东西。我最好记下这是一个双指针。好的,现在,他想把IP分配给DP。但是…坚持!ip是一个整数,dp是一个双精度数。我不能那样做!

    …编译器在屏幕上呕吐…

    事实同时比上面的要简单得多(因为计算机根本就不思考任何东西——它是非常机械的),而且要复杂得多(因为我已经详细讨论了机械过程中的大约十亿个细节)。

        4
  •  1
  •   Khaled Alshaya    15 年前

    这是将源代码转换为机器代码的语法分析的一部分。在最简单的示例中,您可以将其视为检查分配两侧的类型:

    dest = source
    // make sure that type of source == type of dest
    
        5
  •  1
  •   danben    15 年前

    指针只保存一个内存地址,而不保存其他内容。

    意识到在汇编的级别(所有C/C++代码都被翻译成),在高级语言中不存在任何类型的概念。asm指令都在二进制值(字节、字、双字等)上运行,而不太关心程序是否认为给定的位集是int、char或其他什么。

    (当然,除了我们对整数值和浮点值有不同的操作说明,但这并不是讨论的重点。)

    因此,简短的答案是,类型完全是编译时构造,并存储在 symbol table 在编译器程序内部,将标识符映射到类型。在正在编译的程序中,类型不存在。

        6
  •  0
  •   Dummy00001    15 年前

    大小等于操作系统的字

    CPU word 你想说?最好不要用 word 将一个类型描述为术语严重过载,并且取决于读者的背景,可能很容易被误解。

    只是因为您不能在一个类型上有一个指针,并且不能将另一个具有不同类型的指针赋给该指针。

    视情况而定。继续阅读: Von Neumann architecture

        7
  •  0
  •   Arkadiy    15 年前

    在现代体系结构中,没有关于内存字是命令、数字、字符串的一部分还是指针的运行时信息。编译完成后,所有这些信息都将丢失(尽管在调试符号中可能仍然可用)。如果一个单词被编译后的代码用作指针,那么它必须是一个指针——CPU将不会为您检查。

    用于在运行时维护此信息的较旧、更奇特的体系结构。请看这里: http://wapedia.mobi/en/Burroughs_large_systems?p=2