什么做指针'实际上'引擎盖下?

时间:2015-08-07 12:09:19

标签: c pointers

说我有以下c代码:

int* vector = (int*)malloc(5 * sizeof(int));

malloc返回一个void指针,因为我们不知道要求为其分配空间。

因此,我们将void指针转换为int指针。

演员是否在运行时实际执行任何操作,还是仅仅需要编译?如果它在运行时工作,它在做什么?

4 个答案:

答案 0 :(得分:3)

在编译时需要转换指针,除了指向void的指针之外,可以转换为指向任何类型的指针,或者指向任何类型的指针,而不进行显式转换。

语言未指定在运行时发生的情况,但指向char的指针和指向void的指针需要具有相同的表示。对于剩下的东西,唯一需要的是(6.3.2.3转换/指针§7)指向对象或不完整类型的指针可以转换为指向不同的指针 对象或不完整的类型。如果生成的指针未正确对齐 指向类型,行为未定义。否则,当再次转换回来时, 结果应与原始指针

进行比较

但是在常见的体系结构中,指向任何对象的指针的表示形式是其第一个字节的地址。因此,运行时的指针转换是无操作。

答案 1 :(得分:2)

投射指针可以做一些非常重要的事情。但是,通常指向特定地址的任何类型的指针都具有相同的表示形式,因此强制转换不会执行任何操作。

那就是说,只有代码是以面值实现的;优化会发生各种各样的疯狂事情,因此包含可执行文件的机器代码不会直接对应源代码。 (当然,在这种情况下,仍然可能没有任何东西对应于演员)

答案 2 :(得分:0)

演员阵容在运行时没有做任何事情。它在编译时使用,让编译器知道你实际上打算将一种数据类型视为另一种数据类型。

void *是特殊的,因为在C(但不是C ++)中,您可以在void *之间分配任何(非功能)指针,而不会让编译器警告您它

正因为如此,你不应该像你在你的例子中那样对void *进行投射。在malloc这样做的情况下,可以掩盖您忘记#include <stdlib.h>这一事实,这可能会导致代码中其他地方出现一些微妙的错误。

答案 3 :(得分:0)

在一些旧类型的机器上(我学习编程C的机器),内存位置的char *地址的值与同一位置的int *地址的值不同,即使假设地址已经充分对齐。有问题的计算机是名为ICLThree RiversPerq台计算机。

Perq是一个微编码的机器 - 如果你足够好,你可以添加到它的指令集。它的基本寻址单元是一个16位字。地址是字符指针,以及它是否被寻址的偶数或奇数字节的事实是在高阶或最高有效地址位中编码的,而不是最低有效或低阶地址位。这是在从1 MiB增加到2 MiB主存储器的时间内,程序运行的内存大约是5倍 - 因为o / s使用了大约3/4 MiB;不考虑处理千兆字节的内存(哎呀,磁盘驱动器远小于1 GiB,更不用说主内存了)。因此,&#39;浪费的比特&#39;在地址中也不是问题。

这也是在最早的C标准之前很久的时间。像malloc()这样的内存分配函数定义为:

extern char *malloc();  /* No prototypes - no <stdlib.h> either */

如果你在使用之前忘记宣布这个功能,那么你会感到懊恼。返回的值将非常错误管理,您的程序将崩溃。而且,在那些日子里,有必要施放malloc()的结果。当时的编译器没有选择来帮助你发现问题; lint计划,现已降级为历史垃圾箱,是一项重要检查,有助于确保您的计划编码正确。

所以,在一些真实的(但现在是古老的)系统中,强制转换会真正改变指针的位模式。

一些大型机系统在其指针中编码了类型信息 - ICL 2900 Series机器就是一个例子。 C很难移植到这样的系统。